1752. Check if Array Is Sorted and Rotated - Explanation
Description
You are given an array nums, return true if the array was originally sorted in non-decreasing order, then rotated some number of positions (including zero). Otherwise, return false.
There may be duplicates in the original array.
Note: An array A rotated by x positions results in an array B of the same length such that B[i] == A[(i+x) % A.length] for every valid index i.
Example 1:
Input: nums = [3,4,5,1,2]
Output: trueExplanation: [1,2,3,4,5] is the original sorted array.
You can rotate the array by x = 2 positions to begin on the element of value 3: [3,4,5,1,2].
Example 2:
Input: nums = [2,1,3,4]
Output: falseExplanation: There is no sorted array once rotated that can make nums.
Example 3:
Input: nums = [1,2,3]
Output: trueExplanation: [1,2,3] is the original sorted array.
You can rotate the array by x = 0 positions (i.e. no rotation) to make nums.
Constraints:
1 <= nums.length <= 1001 <= nums[i] <= 100
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Array Traversal - Iterating through arrays and comparing adjacent elements
- Modulo Arithmetic - Using modulo to handle circular array indexing (wrap-around)
- Sorted Array Properties - Understanding non-decreasing order and rotation concepts
1. Brute Force
Intuition
A sorted and rotated array can be thought of as taking a sorted array and moving some elements from the end to the beginning. For example, [3,4,5,1,2] is [1,2,3,4,5] rotated. We can verify this by sorting the array and checking if our original array matches some rotation of the sorted version.
Algorithm
- Create a sorted copy of the input array.
- Try every possible rotation (
0ton-1positions). - For each rotation amount
i, compare the original array with the sorted array rotated byipositions. - To compare, check elements from position
n-iton-1of the sorted array against the beginning of the original, then elements from position0ton-i-1against the rest. - If any rotation matches the original array, return
true. - If no rotation matches, return
false.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Sliding Window
Intuition
If we imagine the array as circular (the last element connects back to the first), a valid sorted-and-rotated array should have a contiguous segment of length n where elements are in non-decreasing order. We can simulate this circular behavior by conceptually doubling the array and looking for n consecutive non-decreasing elements.
Algorithm
- Iterate through indices
1to2n-1, treating the array as circular using modulo operations. - Maintain a count of consecutive non-decreasing pairs.
- If the current element (at index
i % n) is greater than or equal to the previous element, increment the count. - Otherwise, reset the count to
1. - If at any point the count reaches
n, we found a valid sorted sequence, so returntrue. - Handle the edge case where
nequals1by returningtrueat the end.
Time & Space Complexity
- Time complexity:
- Space complexity:
3. Iteration
Intuition
In a sorted-and-rotated array, there can be at most one "break point" where a larger element is followed by a smaller element. This break point is where the rotation occurred. If we find more than one such break, the array cannot be a valid rotation of a sorted array.
Algorithm
- Initialize a counter for the number of break points (where an element is greater than its next element).
- Iterate through the array, comparing each element with the next one (using modulo to wrap around from the last element to the first).
- If the current element is greater than the next element, increment the break counter.
- If the counter exceeds
1at any point, returnfalseimmediately. - After checking all pairs, return
true(at most one break was found).
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Forgetting to Check the Wrap-Around
A sorted and rotated array is circular, so you must compare the last element with the first element. Using nums[i] > nums[i + 1] without modulo wrapping misses the case where the "break" occurs between the last and first elements.
# Wrong: if nums[i] > nums[i + 1]
# Correct:
if nums[i] > nums[(i + 1) % N]Expecting Strictly Increasing Order
The problem allows non-decreasing order (duplicates are permitted). Checking for strict inequality nums[i] >= nums[i+1] instead of nums[i] > nums[i+1] incorrectly flags valid arrays like [1, 1, 1] or [2, 2, 3, 1, 1] as invalid.
Sign in to join the discussion