5 Best Ways to Check if Right Rotation Forms Increasing or Decreasing Array with First N Natural Numbers in Python

πŸ’‘ Problem Formulation: We’re tasked with determining whether a right rotation of a sequence containing the first n natural numbers results in an increasing or decreasing array. Assume we receive an input array that is a right rotation of the sequence [1, 2, …, n] and we want to check if this array is sorted in ascending or descending order.

Method 1: Brute Force Checking

This method involves sequentially comparing each element to the next to determine the direction of the sequence after the rotation. It is simple to understand and implement, and functions by directly validating the sorted nature of the rotated array.

Here’s an example:

def is_sorted_rotated(arr):
    increasing = all(arr[i] <= arr[i + 1] for i in range(len(arr) - 1))
    decreasing = all(arr[i] >= arr[i + 1] for i in range(len(arr) - 1))
    return increasing or decreasing

# Test case
arr = [3, 4, 5, 1, 2]
print(is_sorted_rotated(arr))

Output:

True

This code snippet defines a function is_sorted_rotated that checks for both increasing and decreasing order using Python’s all() function combined with a generator expression. It returns True if the array is sorted in either direction, and False otherwise.

Method 2: Using Python Slicing

Python slicing can be utilized to quickly check if the array, when rotated, forms an increasing or decreasing sequence. This method takes advantage of Python’s negative indexing and list slicing features.

Here’s an example:

def check_rotation(arr, n):
    return arr == sorted(arr) or arr == sorted(arr, reverse=True)

# Test Case
arr = [3, 4, 5, 1, 2]
print(check_rotation(arr, 5))

Output:

True

The check_rotation function sorts the array in both ascending and descending order and compares it with the original array to check if it forms a sorted sequence upon rotation. The function returns True for a sorted sequence, reflecting that the array forms either an increasing or decreasing sequence when rotated.

Method 3: Using Array Rotation Logic

In this method, the array is actually rotated step by step until it returns to its original position, confirming the increasing or decreasing order after each rotation. It’s more computationally intensive but allows visualization of the rotation process.

Here’s an example:

def rotate_and_check(arr, n):
    for i in range(n):
        if arr == sorted(arr) or arr == sorted(arr, reverse=True):
            return True
        arr = arr[-1:] + arr[:-1]
    return False

# Test Case
arr = [3, 4, 5, 1, 2]
print(rotate_and_check(arr, len(arr)))

Output:

True

The rotate_and_check function iteratively rotates the array to the right and checks for sorted order after each rotation. If it finds the array to be sorted at any rotation, it returns True, confirming that a right rotation can yield an increasing or decreasing sequence.

Method 4: Optimized Rotated Array Check

This method looks at the relationship between adjacent elements and the first and last elements to infer if the array has been sorted upon rotation. It’s a more optimized approach since it requires fewer comparisons.

Here’s an example:

def optimized_rotation_check(arr):
    if arr[0] > arr[-1]:
        return all(arr[i] >= arr[i + 1] for i in range(len(arr) - 1))
    else:
        return all(arr[i] <= arr[i + 1] for i in range(len(arr) - 1))

# Test Case
arr = [3, 4, 5, 1, 2]
print(optimized_rotation_check(arr))

Output:

True

The optimized_rotation_check function uses the first and last elements of the array to determine whether it should be in ascending or descending order, and then validates this with a loop. This reduces the number of checks needed to confirm the order of the rotated array.

Bonus One-Liner Method 5: Using Min-Max Positions

The one-liner approach leverages the idea that, in a correctly rotated increasing or decreasing sequence, the maximum and minimum elements should be adjacent.

Here’s an example:

# Assuming the array is a right rotation of the first n natural numbers
def is_sorted_one_liner(arr):
    i_min = arr.index(min(arr))
    return arr[i_min - 1] == max(arr) or arr[(i_min + 1) % len(arr)] == max(arr)

# Test Case
arr = [3, 4, 5, 1, 2]
print(is_sorted_one_liner(arr))

Output:

True

The is_sorted_one_liner function computes the index of the minimum element and checks if its neighbors are the maximum. It elegantly summarizes the checking logic into a single line of code, making it a neat and quick method at the cost of readability for those new to Python.

Summary/Discussion

  • Method 1: Brute Force Checking. Easy to understand. May be slower for large arrays due to the number of comparisons.
  • Method 2: Using Python Slicing. Slicing simplifies the code. However, sorting operations can be costly in terms of time complexity.
  • Method 3: Using Array Rotation Logic. Visually illustrates the rotation process. Can be inefficient if many rotations are needed.
  • Method 4: Optimized Rotated Array Check. More efficient with fewer comparisons. Requires understanding of the array’s first and last elements’ relationship.
  • Method 5: Using Min-Max Positions. Quick and clever. Can be less intuitive for beginners and is specific to problems involving natural numbers.