Check if Array Is Sorted and Rotated

Rotate Array is a preceding problem that must be solved before this problem.

This problem is about determining if a given array of integers, nums, can be derived from a non-decreasing array by some number of rotations. If it can, we return true; if not, we return false.

Let’s consider the characteristics of a rotated non-decreasing array. If we rotate a non-decreasing array at least once, it splits the order: we’ll have a portion of larger values followed by smaller ones. And it should happen only once due to the nature of rotation. If the array is not rotated, it is still considered as valid since it follows the non-decreasing order.

Based on these observations, we can use the following approach to solve the problem:

  1. Traverse the nums array from left to right.
  2. Look for a position where nums[i] > nums[i+1], which indicates the rotation point. Count these points.
  3. If we find more than one such point, return false because a rotated sorted array can have at most one position where the order breaks.
  4. If we don’t find any such points, the array is already sorted in non-decreasing order. Return true.
  5. If we find exactly one such point, we need to make sure that the last element of the array is not greater than the first one because a valid rotated non-decreasing array wouldn’t allow this (think about the rotation of a sorted array). If nums[n-1] > nums[0], return false; otherwise, return true.

Here is the Python code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from typing import List

class Solution:
    def check(self, nums: List[int]) -> bool:
        count = 0
        n = len(nums)

        for i in range(n - 1):
            if nums[i] > nums[i + 1]:
                count += 1

        if count > 1 or (count == 1 and nums[n - 1] > nums[0]):
            return False

        return True

In this solution, count keeps track of the number of times the next number is less than the current one in nums, which should only happen at most once in a rotated non-decreasing array. The function check(nums) will return True if the array nums could be a rotated non-decreasing array and False otherwise.

This code has a linear time complexity, O(n), because it only needs to traverse the array once. It also has a constant space complexity, O(1), since it only uses a few variables and doesn’t require extra space that scales with the input size.

This approach will solve the given problem according to the constraints mentioned. For larger inputs, you might need more efficient algorithms, but for the given constraints, this approach will work within a reasonable amount of time.

How do we know that there are no missing numbers in this logic?

The problem statement doesn’t require us to consider missing numbers. The focus is to determine if the given array could have been a non-decreasing (sorted) array that was rotated some number of times.

In fact, since rotation involves moving elements without deletion or insertion, it can’t introduce or remove numbers. The array length remains the same before and after rotation. Therefore, whether or not some numbers are “missing” from the series isn’t relevant for the problem’s requirements.

Our logic operates on the basis of relative ordering of numbers, specifically, we look for the point of rotation where the sequence goes from a larger number to a smaller one. This rotation point can happen at most once in a rotated sorted array.

Hence, the presence or absence of certain numbers in the array doesn’t affect this approach. It will still correctly identify whether the given array could be a rotated version of some non-decreasing array or not.

I meant if a number is skipped in the given input, this logic still works? How?

Yes, the logic will still work even if numbers are “skipped” or not consecutively increasing in the array. The key reason is that the problem doesn’t require the original sorted array to be strictly increasing by 1 each time.

It’s worth noting the difference between a sorted (non-decreasing) array and a strictly increasing one. A sorted array allows for repeated numbers and doesn’t require each number to be the previous number plus one. In other words, [1, 2, 4, 7] and [2, 2, 3, 5, 9] are both valid sorted arrays.

The logic we have implemented checks if the array is a rotated version of a non-decreasing (sorted) array. It does this by looking for the point of rotation, which is where the numbers drop from a larger one to a smaller one.

In the sorted arrays mentioned above, if we rotate them, we could get [7, 1, 2, 4] and [5, 9, 2, 2, 3] respectively. If we apply the logic to these arrays, it correctly identifies them as rotated sorted arrays, even though they have numbers that are not consecutive.

So, the logic holds even if some numbers are skipped in the input. It relies on the relative order of the numbers, not on them being a consecutive sequence.

Invariant

Invariants are conditions that remain true regardless of the operations or transformations performed within a particular context. They’re helpful in problem-solving, particularly in algorithms, because they help us reason about the behavior of the algorithm and its correctness.

In the context of this problem, the invariant is the property that a sorted and rotated array will have at most one place where the array elements are not in a non-decreasing order. This drop from a larger number to a smaller one represents the point of rotation.

No matter how many times we rotate a sorted array, this property remains true: we will always have at most one drop, which is the transition from the end of the array back to the beginning.

Thus, we use this invariant to guide our algorithm. As we scan through the array, we maintain a count of the number of drops we encounter. If we find more than one, we know the array could not have been sorted and then rotated, and we return False. Otherwise, if we encounter none or exactly one such drop, the array could be a rotated sorted array, so we return True.

This invariant holds at every point in our algorithm and helps ensure its correctness.

Loop Invariant

A loop invariant is a condition that is initially true and remains true after each iteration of a loop. It’s used to help understand and verify the correctness of algorithms.

In this specific problem, a suitable loop invariant would be the following: At each iteration of the loop, count represents the number of times we’ve seen a decrease from one element to the next in the array up to the current index i.

Before the loop starts (initialization), count is 0 which is correct since we haven’t checked any elements yet. After each iteration of the loop (maintenance), we update count if we find nums[i] > nums[i + 1]. Therefore, count correctly represents the number of decreases found in the array from the start up to index i.

Finally, when the loop terminates (termination), we’ve checked all elements in the array, and count represents the total number of times we’ve seen a decrease from one element to the next in the entire array. We then use count to decide whether the array could have been a rotated sorted array or not.

Thus, the loop invariant is maintained throughout the execution of the algorithm, helping us to reason about its correctness.

Invariant vs Loop Invariant

The concepts of invariants and loop invariants are related but not exactly the same.

An invariant is a condition or property that remains unchanged throughout the execution of an algorithm or system. It’s a broader concept and can refer to a property that holds true before, during, and after any operation in a system.

A loop invariant, on the other hand, is a type of invariant that applies specifically to loops in an algorithm. It is a condition that is initially true before the loop starts, remains true after each iteration of the loop, and is still true after the loop ends.

In the context of this problem:

The general invariant is: “A rotated, non-decreasing array has at most one drop in value.”

The loop invariant for our specific algorithm is: “At the start of each iteration of the loop, count holds the number of drops in value found in the array so far.”

While both invariants relate to the same problem and algorithm, they’re describing slightly different things. The general invariant describes a property of the problem we’re trying to solve, while the loop invariant describes a property of our specific algorithm’s operation.

Building Blocks

The building blocks of this solution are:

  1. Array Traversal: You need to navigate through each element of the array to examine and compare adjacent elements. This fundamental programming concept is used to check for decreases in the array values.

  2. Comparison: You compare each element of the array with its next neighbor to detect decreases in value. You need to understand how to use comparison operators (like > and <) to solve this problem.

  3. Conditional Logic: The use of if-else conditions is vital in this solution. It allows the program to decide what to do based on whether a certain condition is met. In this case, it’s used to decide when to increment the count of decreases and whether to return true or false at the end.

  4. Looping: You use a loop to traverse the array. This enables you to perform the same set of operations (comparisons and possible increment) on each element of the array.

  5. Modulo Operation: The modulo operation is used to wrap around to the start of the array when comparing the last element to the first. Understanding this operation is key to working with circular or rotated data structures.

  6. Counting: The solution keeps a count of the times the array decreases from one element to the next. This is an example of using a simple count to track occurrences of an event (in this case, decreases) while traversing a data structure.

Together, these building blocks form the strategy for solving this problem. Understanding these concepts allows you to recognize similar problems and apply the same or similar strategies to solve them.

Yes, you’ve correctly identified some key building blocks of this solution:

  1. Neighbor Comparison: Comparing each element in the array with its neighbor is a fundamental step in this solution. It helps us identify where the array value decreases, which indicates the rotation point in the array.

  2. First Last Comparison: This is crucial in solving this problem because we are dealing with a potentially rotated array. The rotation could place the last element before the first one, so we need to compare these elements as well.

  3. Counter: We maintain a counter to keep track of how many times we find a decrease in the array values. This helps us determine whether the array could be a sorted and rotated array or not. If there’s more than one decrease, we can conclude it’s not a sorted and rotated array.

Each of these building blocks plays a crucial role in solving the problem. Recognizing these patterns can be beneficial when you encounter other similar problems. You can take these concepts and apply them to new problems, which is a valuable skill in problem-solving.

At the abstract level, we can recognize a few more conceptual components:

  1. Pattern Recognition: This solution fundamentally relies on identifying a specific pattern within the data - namely, the property of sorted arrays that have been rotated. Recognizing this pattern is key to understanding and solving the problem.

  2. Invariant Identification: The property that an array is non-decreasing except for a single rotation point acts as an invariant in this problem. This means it’s a condition that holds true throughout the execution of the algorithm. Identifying invariants is a common technique in algorithm design.

  3. Boundary Handling: Comparing the first and last elements in the array is a form of boundary handling, an important concept in problems involving arrays or other data structures with defined start and end points. Correctly handling these edge cases is crucial to ensuring the algorithm’s correctness.

  4. Condition Evaluation: The solution uses condition evaluations (like if statements) to make decisions during its execution. These conditions are based on the observations made during the array traversal, such as whether a number is greater than its next number.

Each of these abstract components can be found in many problem-solving scenarios, not just coding. Being able to recognize and apply these concepts is crucial for effective problem-solving.

Absolutely, in the context of this specific problem, identifying the rotation in the array is a much more precise characterization of the problem-solving strategy being applied. “Rotation Identification” implies understanding the concept of a sorted array that has been rotated, and designing an approach to detect this rotation.

In this problem, you’re recognizing the specific pattern of “rotation” in an array: a sequence that remains consistent except for a shift in start position. This is a more refined, problem-specific interpretation of pattern recognition. This kind of precision can be very useful when trying to draw connections between problems or to articulate the essence of a problem-solving strategy.

The term “Pattern Recognition” is indeed a broader concept, and “Rotation Identification” can be considered a specific instance of pattern recognition tailored to this problem.

Q&A

I wrote the following code, it works on all the testcases but it shows an error(written below code) when i submit it

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
  public: bool check(vector & nums) {

    int n = nums.size();
    int i = 1;
    int k = 1;
    while (nums[k] > nums[k - 1]) {
      k++;
    }

    vector < int > temp(n);
    vector < int > temp2 = nums;
    sort(temp2.begin(), temp2.end());
    for (int i = 0; i < n; i++) {
      temp[(i + k) % n] = temp2[i];

    }

    for (int i = 0; i < n; i++) {
      cout << temp[i] << " ";
    }
    if (nums == temp) {
      return true;
    } else {
      return false;
    }
  }
};

Error:

AddressSanitizer: heap-buffer-overflow on address …

The error message you’re seeing suggests that there’s an issue of heap-buffer-overflow. This error usually occurs when your program tries to access memory that it’s not supposed to. In your case, it’s likely due to an off-by-one error in your code.

In your loop where you fill temp, you’re using the variable k as an offset:

1
2
3
for(int i = 0; i < n; i++){
    temp[(i+k)%n] = temp2[i]; 
}

The loop where you are increasing k does not have a boundary check:

1
2
3
while(nums[k]>nums[k-1]){
    k++;
}

The error occurs when nums[k] > nums[k-1] for all k < n, so k equals n at the end of the loop. When you use k as an offset in (i+k)%n, and i is also iterating up to n-1, you end up trying to access temp[n], which is out-of-bounds.

To fix this issue, you should modify your loop condition as follows:

1
2
3
while(k < n && nums[k] > nums[k-1]){
    k++;
}

This modification will ensure that k will always be less than n, thus avoiding the heap-buffer-overflow error.

Comparing the last element with the first element is needed to account for the rotation in the array.

Recall the problem statement: we want to check if the given array is a sorted array that’s been rotated. A sorted and rotated array is one where the elements are in ascending order, but the start of the sequence has been moved. For example, [4,5,1,2,3] is a sorted and rotated array where the original sorted array was [1,2,3,4,5].

In such an array, the only place where an element is larger than the following element is at the rotation point, which is between the last element and the first element (in this example, between 5 and 1).

If the array is a sorted and rotated array, there can be at most one place where an element is larger than the next element (the rotation point). So, in the process of checking the array to see if it fits this condition, we need to compare every pair of adjacent elements, including the last element and the first element.

If we find more than one place where an element is larger than the next element, we know the array is not a sorted and rotated array.

I have written this code .. Do you have a more optimised logic for this problem? If you have , please share. —>

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Solution {
  public: bool check(vector & nums) {
    int n = nums.size();
    int count = 0;
    int b = -1;
    int count2 = 0;
    int k = 0;
    for (int i = 0; i < n - 1;) {
      if (nums[i] <= nums[i + 1]) {
        count++;
        i++;
      } else {
        b = i;
        k = nums[i];
        break;
      }
    }
    if (b > -1) {
      for (int i = b + 1; i < n; i++) {
        if (i == b + 1) {
          if (nums[i] <= k && nums[i] <= nums[0])
            count2++;
        } else {
          if (nums[i] <= k && nums[i] >= nums[i - 1] && nums[i] <= nums[0])
            count2++;
        }
      }
    }
    if (count + count2 == n - 1)
      return true;

    else
      return false;
  }
};

Your current solution correctly checks for the non-decreasing order in the array and the rotation point. However, you can simplify and optimize your code a bit by removing some unnecessary variables and operations.

Here’s a more streamlined version of your code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
public:
    bool check(vector<int>& nums) {
        int n = nums.size();
        int decreaseCount = 0;
        
        for(int i = 0; i < n; i++){
            if(nums[i] > nums[(i + 1) % n]) {
                decreaseCount++;
            }
        }
        
        return decreaseCount <= 1;
    }
};

This code does the following:

  1. It traverses the array once, checking each element and its next neighbor, with the modulo operation ensuring the last element is compared with the first one.

  2. Whenever it finds a number larger than its next neighbor, it increments decreaseCount.

  3. If decreaseCount is more than one, it returns false, because a sorted and rotated array can have at most one decrease point. If decreaseCount is one or zero, it returns true.

This solution still has a time complexity of O(n) like your original solution, but it’s cleaner and more concise.

Why is this given: A[i] == B[(i+x) % A.length] It is not used in the code.

The expression A[i] == B[(i+x) % A.length] in the problem statement is not something that you need to directly implement in the solution. Instead, it’s explaining the property of a rotated array, and how elements in the original sorted array A map to their new positions in the rotated array B.

If an array is rotated x positions to the right, the i-th element in the original array will be found at the (i+x) % A.length position in the rotated array. The modulo operation (%) is used to handle the “wrap-around” that occurs with rotation. If i+x exceeds the length of the array, it wraps around to the beginning.

Understanding this property is essential to conceptualizing the problem, but you don’t explicitly use this formula in your solution code. Instead, you use the concept that a rotated, sorted array will have at most one “drop” in value to determine if the given array fits the criteria. The “drop” represents the rotation point.

Yes, absolutely. The “drop” in the context of this problem refers to the point at which the array elements decrease from one to the next. This “drop” could be of any size.

For example, if you have a sorted array like [1, 2, 3, 4, 5] and you rotate it 3 positions to the right, you get [3, 4, 5, 1, 2]. The “drop” is between 5 and 1. It’s not a decrease of one unit, but rather of four units.

So, in this problem, the decrease could indeed be any number, not necessarily one. The important part is that there should be only one such “drop” in a sorted and rotated array. If there are more than one, the array can’t be a sorted array that’s been rotated.

Dip would be a better term than drop in that case

Yes, “dip” can be a more accurate term to describe this concept. A “dip” implies a decrease or downward movement, which accurately describes the transition from a larger number to a smaller one in a sorted, rotated array. This term doesn’t imply any specific quantity of decrease, and hence, is more general. It’s indeed important to choose precise terminology when explaining problem-solving strategies, and “dip” seems fitting for this problem.

We cannot double dip in this problem?

Correct. In the context of this problem, “double dipping” would mean having more than one “dip” or decrease in the array values. This is not allowed because the problem asks us to verify if the given array can be a sorted array that has been rotated some number of times. A sorted array has a property that all the elements are in non-decreasing order, meaning each element is equal to or greater than the previous one. When we rotate such an array, we disrupt this order at most one place, creating a single “dip”. Hence, a sorted and rotated array can have at most one “dip”. If there are more than one, the array cannot be a sorted array that’s been rotated.

There is a relationship between the first and last element in the given input. How to identify this relationship to get the key insight to express in the code?

The relationship between the first and last elements of the array is critical in this problem. Here’s how we identify it:

In a sorted, non-decreasing array, the last element is always greater than or equal to the first element. When we rotate this array, we disrupt this order creating a “dip”, or a point where an element is less than its preceding element. This “dip” can occur between any two elements, including between the last and the first elements.

The key insight here is that a rotated, sorted array can have at most one “dip”. So, we need to check the entire array for this “dip”, and that includes comparing the last element to the first one. If we find more than one “dip”, or if the only “dip” we find is not between the last and first elements (in an array of size greater than 2), we know the array isn’t a sorted array that’s been rotated.

Expressing this in the code involves looping through the array and comparing each element to its next neighbor, with the next neighbor of the last element being the first element. We then count the number of “dips”. If this count is more than one, we return false; otherwise, we return true.

Certainly, visual representation can help understand the concept better.

Let’s take a sorted array [1, 2, 3, 4, 5]. When we graph these numbers, we get a straight line rising to the right:

5 -  *  
4 -     *  
3 -       *  
2 -         *  
1 -           *  
   -----------
    1 2 3 4 5

Now, if we rotate this array two positions to the right, we get [4, 5, 1, 2, 3]:

5 -  *  
4 - *  
3 -     *  
2 -       *  
1 -         *  
   -----------
    4 5 1 2 3

The line from 5 to 1 is a “dip” in the values. Notice how this “dip” occurs only once.

Now, let’s look at an array that isn’t a sorted and rotated array: [3, 4, 1, 2]

4 -  *  
3 - *  
2 -     *  
1 -       *  
   -----------
    3 4 1 2

In this case, we have two “dips” - from 4 to 1 and from 2 back to 3 when we loop back to the start. Hence, this array can’t be a sorted array that’s been rotated.

In conclusion, the visual representation helps us understand that in a sorted and rotated array, there is at most one dip in the values from one element to the next, and this includes the transition from the last element to the first one. This is the key insight we need to solve this problem.

The rotation property condition that was given in the problem statement can be used as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    public boolean check(int[] A) {
        int k = 0, n = A.length;
        for (int i = 0; i < n; ++i) {
            if (A[i] > A[(i + 1) % n]) {
                k++;
            }
            if (k > 1) {
                return false;
            }
        }
        return true;
    }

The equivalent Python 3 code would be:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution:
    def check(self, nums: List[int]) -> bool:
        k = 0
        n = len(nums)
        for i in range(n):
            if nums[i] > nums[(i + 1) % n]:
                k += 1
            if k > 1:
                return False
        return True

This Python code follows the same logic as the Java code you provided. It loops through the array and checks whether each element is greater than the next one (with the last element’s “next one” being the first element). It increments a counter each time it finds such a pair, and if the counter goes above 1 (meaning there is more than one “dip” in the array), it returns False. If it completes the loop without the counter going above 1, it returns True.

Earlier you said the condition given in the problem statement cannot be used in code. It seems simpler to use it to express the rotation in code.

Indeed, using the rotation property as you have shown is a more efficient and direct way of solving this problem. It’s a great demonstration of how understanding the problem conditions deeply can lead to more straightforward and efficient solutions.

The rotation condition A[i] == B[(i+x) % A.length] given in the problem statement helps us understand the concept of array rotation and allows us to formulate our solution. This condition essentially says that a rotation is equivalent to shifting elements while preserving their relative order, and it provides a framework for iterating over the array and comparing each element with the next (taking the array as circular).

Applying this condition in the code, we compare each element with its next element, counting the number of “dips” or decreases. If we find more than one, we return false. If we traverse the entire array with at most one “dip”, we return true.

This is indeed a more straightforward, and also computationally more efficient, approach to solving the problem. I appreciate your patience and your keen insight on this problem.

This condition in the problem statement: A[i] == B[(i+x) % A.length] has been expressed as nums[i] > nums[(i + 1) % n] in code. Explain this transformation.

The condition given in the problem statement: A[i] == B[(i+x) % A.length] is indeed the definition of a rotation. This allows us to understand how a rotation would rearrange the elements of the array. But to solve this problem, we don’t directly use this condition as is, but rather, we use a concept derived from it.

The condition we use in the code, nums[i] > nums[(i + 1) % n], doesn’t directly map to the rotation definition. Instead, it is used to find the “dip” or decrease in the array’s values, which in turn helps us identify if the array is a rotated version of a sorted array.

Here is how we derived this condition:

  1. For a sorted and rotated array, there should be at most one “dip” or decrease in the sequence. This “dip” is the point of rotation. This is what we infer from the rotation definition.

  2. To identify the “dip”, we compare each element with the next one in the array. This is represented as nums[i] > nums[i + 1]. The “>” operator checks if the current element is greater than the next one, which signifies a “dip”.

  3. To handle the case where the array wraps around from the last element to the first one (as it’s a rotation), we use the modulo operator “%”. This gives us nums[i] > nums[(i + 1) % n]. Here, (i + 1) % n will be zero when i reaches the end of the array, which means we’re comparing the last element with the first one.

So, while we don’t directly use the rotation definition in the code, we use the concept of a rotation and the property of a sorted array (that it should have at most one “dip” if rotated) to formulate our condition for the solution.

In this case, since me use the modulo operator, we don’t need to check the first and last element explicitly in the code?

Correct. The use of the modulo operator % in the expression nums[(i + 1) % n] ensures that when i reaches the end of the array, (i + 1) % n becomes zero, effectively comparing the last element with the first one. This takes care of the “wrap-around” or circular nature of a rotated array.

So, by using this expression, you are indeed implicitly checking the relationship between the last element and the first element without the need to write additional explicit code to handle this case. This is one of the ways that understanding the problem’s requirements and properties can lead to cleaner and more efficient code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    public boolean check(int[] A) {
        int k = 0, n = A.length;
        for (int i = 0; i < n; ++i) {
            if (A[i] > A[(i + 1) % n]) {
                k++;
            }
            if (k > 1) {
                return false;
            }
        }
        return true;
    }

This is a simple Java function called check. Its purpose is to determine if the input array A is rotated.

Here’s the breakdown of the code:

  1. We initialize a counter k to 0 and n to the size of the array A.

  2. We then run a loop from 0 to n (exclusive). For each i, we compare the i-th element with the (i + 1)%n-th element. (i + 1)%n ensures that we are comparing each element with its next one in a circular manner. When we reach the end of the array, we wrap around to the first element.

  3. If the i-th element is greater than its successor, we increment k.

  4. If at any point k becomes greater than 1, we immediately return false. This is because in a rotated sorted array, there should be at most one place where the next number is smaller than the current one. If there are more than one such places, then the array is not a rotated sorted array.

  5. If we finish the loop without returning, it means that k is 0 or 1, which implies that A is a rotated sorted array. We return true in this case.

The time complexity of this function is O(n), where n is the number of elements in the array, because we are iterating through the array once. The space complexity is O(1), because we are using a constant amount of space to store k and n.

NonSequence = nums[i] > nums[i+1] i.e. number is greater than its right.

Find non sequences count. – In case of sorted array there will be 0 nonsequences. [1,2,3,4,5] – In case of rotated sorted array there will be 1 nonsequence. [3,4,5,1,2] – In other cases like [2,1,3,4] nonsequences > 1 ==> 2

How to count 4 > 2, in that case we need nums[i] > nums[(i+1)%len]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
    public boolean check(int[] nums) {
        int nonsequence = 0;
        
        for(int i=0; i<nums.length; i++){
            if(nums[i] > nums[(i+1)%nums.length]){
                if(nonsequence == 1) return false;
                nonsequence++;
            }
        }
        
        return true;
        
    }
}

This is a Java class named Solution which contains a public method check. This method, similar to the previous one, is used to determine if the input array nums is a rotated sorted array.

Here’s a breakdown of the method:

  1. An integer nonsequence is initialized to 0. This variable will keep track of the number of times the array elements are not in increasing sequence.

  2. The method then runs a loop from 0 to the length of the array nums.

  3. Inside the loop, for each index i, it checks if the i-th element is greater than the (i + 1)%nums.length-th element. The (i + 1)%nums.length ensures a circular comparison, where the last element is compared with the first.

  4. If the i-th element is greater than its next element, it checks if nonsequence is already 1. If it is, it immediately returns false, indicating that the array is not a rotated sorted array. This is because in a rotated sorted array, there can be at most one instance where an element is larger than its next element. If nonsequence is not 1, it increments nonsequence.

  5. If the loop completes without returning, it means nonsequence is either 0 or 1, indicating the array is a rotated sorted array. The method then returns true.

The time complexity of this method is O(n), where n is the number of elements in the array, since it iterates through the array once. The space complexity is O(1), as it uses a constant amount of space to store nonsequence and the loop variable i.

Python3 equivalent:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution:
    def check(self, nums: List[int]) -> bool:
        nonsequence = 0
        
        for i in range(len(nums)):
            if nums[i] > nums[(i + 1) % len(nums)]:
                if nonsequence == 1:
                    return False
                nonsequence += 1
        
        return True

The Python code follows the same logic as the Java code. It loops through the array and checks if each element is greater than the next one (considering the array as circular). If it finds such a pair, it increments a counter. If it encounters a second pair (meaning there is more than one “dip” in the array), it immediately returns False. If it finishes the loop without finding a second “dip”, it returns True.

Can someone please explain, why this rotated array is false. 10,8,7,5,1,2,3 –> expected result : false

Let’s consider the explample 1: [3, 4, 5, 1, 2] and show how it changes with each rotation from 0 to 3:

RotationResultExplanation
0[3, 4, 5, 1, 2]No rotation; the array remains the same.
1[2, 3, 4, 5, 1]Shifted 1 place to the right; 2 comes to the front.
2[1, 2, 3, 4, 5]Shifted 2 places to the right; original sorted array.
3[5, 1, 2, 3, 4]Shifted 3 places to the right; 5 comes to the front.

Here’s a breakdown of what’s happening at each rotation:

  • Rotation 0: The array is the same as the original, no changes.
  • Rotation 1: Every element moves one position to the right, and the last element (2) wraps around to the beginning.
  • Rotation 2: The array becomes sorted in non-decreasing order.
  • Rotation 3: Every element moves one more position to the right, and the last element (5) wraps around to the beginning.

These rotations show how the original array [3, 4, 5, 1, 2] can be derived from a sorted array through rotations, confirming that the original array is a rotated sorted array.

Let’s analyze the array [10, 8, 7, 5, 1, 2, 3] through rotations from 0 to 6 to understand why it cannot be considered a rotated sorted array:

RotationResultExplanation
0[10, 8, 7, 5, 1, 2, 3]No rotation; the array remains the same.
1[3, 10, 8, 7, 5, 1, 2]Shifted 1 place to the right; 3 comes to the front.
2[2, 3, 10, 8, 7, 5, 1]Shifted 2 places to the right; 2 comes to the front.
3[1, 2, 3, 10, 8, 7, 5]Shifted 3 places to the right; 1 comes to the front.
4[5, 1, 2, 3, 10, 8, 7]Shifted 4 places to the right; 5 comes to the front.
5[7, 5, 1, 2, 3, 10, 8]Shifted 5 places to the right; 7 comes to the front.
6[8, 7, 5, 1, 2, 3, 10]Shifted 6 places to the right; 8 comes to the front.

If you carefully analyze the above rotations, you’ll notice that none of the rotations result in a non-decreasing sorted array. In a rotated sorted array, there should be a distinct point where the elements are rotated, forming a continuous non-decreasing sequence. In this case, such a point does not exist, and the rotations do not lead to a sorted array. Therefore, [10, 8, 7, 5, 1, 2, 3] is not a rotated sorted array.

No amount of rotation can make these 10,8,7,5,1,2,3 sorted?

The array 10, 8, 7, 5, 1, 2, 3 cannot be sorted by rotation alone. Rotating an array involves shifting its elements in a way that the array retains its original order, just starting from a different point. In this case, no amount of rotation will align the elements into a non-decreasing (or non-increasing) order.