You are given a 0-indexed array nums of length n containing distinct positive integers. Return the minimum number of right shifts required to sort nums and -1 if this is not possible.
A right shift is defined as shifting the element at index i to index (i + 1) % n, for all indices.
Example 1:
Input: nums = [3,4,5,1,2] Output: 2 Explanation: After the first right shift, nums = [2,3,4,5,1]. After the second right shift, nums = [1,2,3,4,5]. Now nums is sorted; therefore the answer is 2.
Example 2:
Input: nums = [1,3,5] Output: 0 Explanation: nums is already sorted therefore, the answer is 0.
Example 3:
Input: nums = [2,1,4] Output: -1 Explanation: It's impossible to sort the array using right shifts.
Constraints:
1 <= nums.length <= 1001 <= nums[i] <= 100nums contains distinct integers.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for sorting an array with right shifts is like trying out every possible number of shifts. We'll check if the array is sorted after each different number of shifts.
Here's how the algorithm would work step-by-step:
def minimum_right_shifts_to_sort(numbers):
    list_length = len(numbers)
    for shift_count in range(list_length):
        # Create shifted list
        shifted_list = numbers[-shift_count:] + numbers[:-shift_count]
        # Check if the shifted list is sorted
        is_sorted = True
        for index in range(list_length - 1):
            if shifted_list[index] > shifted_list[index + 1]:
                is_sorted = False
                break
        # If sorted, return shift count
        if is_sorted:
            return shift_count
    # Return -1 if cannot be sorted
    return -1The goal is to find the fewest moves to put an out-of-order sequence into the correct order by shifting items from the end to the beginning. Instead of checking every possible number of moves, we look for how much of the sequence is already in order to figure out the solution faster.
Here's how the algorithm would work step-by-step:
def min_right_shifts_to_sort(arr):
    array_length = len(arr)
    longest_increasing_suffix_length = 0
    # Find the longest sorted suffix
    for i in range(array_length - 1):
        if arr[i] > arr[i + 1]:
            
            #The array isn't sorted. Find the longest suffix
            for start_index in range(array_length - 1, -1, -1):
                is_sorted = True
                for j in range(start_index, array_length - 1):
                    if arr[j] > arr[j + 1]:
                        is_sorted = False
                        break
                if is_sorted:
                    longest_increasing_suffix_length = array_length - start_index
                    break
            break
    else:
        # Array is already sorted
        return 0
    # Calculate min shifts based on unsorted part
    minimum_shifts = array_length - longest_increasing_suffix_length
    return minimum_shifts| Case | How to Handle | 
|---|---|
| Null or empty array input | Return 0, as an empty array is considered sorted by default. | 
| Array with only one element | Return 0, as a single-element array is already sorted. | 
| Already sorted array | Return 0, as no shifts are required. | 
| Array sorted in descending order | Iterate through all possible shifts and check for sorted state; if none found, return -1. | 
| Array with all identical elements | Return 0, as identical elements are considered sorted. | 
| Large array exceeding memory constraints | Consider an in-place approach, if possible, to avoid excessive memory usage and potential OutOfMemoryError. | 
| Array where no number of shifts can result in a sorted array | Return -1 when the loop completes without finding a valid sorted array. | 
| Integer overflow when calculating array indices after shifts | Use modulo operator (%) carefully to wrap around correctly and avoid exceeding the array bounds. |