Rotate Arrays with Python: Comprehensive LeetCode 189 Solution for Tech Interview Preparation
Photo by Brooke Cagle on Unsplash
Efficient In-Place Array Rotation in Python | LeetCode Solution Explained
Introduction
Rotating an array is a fundamental algorithm problem, and one commonly asked in coding interviews. The problem is straightforward: given an integer array nums
, you need to rotate the array to the right by k
steps, where k
is a non-negative integer. In this blog, we will go over the problem in detail and explore three different ways to solve it, with a focus on an efficient, in-place solution with O(1)
extra space.
Let’s dive deep into the problem, discuss a few possible approaches, and finally arrive at the optimal solution.
Problem Statement
We are given the following:
An integer array
nums
of lengthn
(1 <= n <= 10^5
).A non-negative integer
k
(0 <= k <= 10^5
).
We need to rotate the array to the right by k
steps.
Example 1:
Input:
nums = [1, 2, 3, 4, 5, 6, 7]
,k = 3
Output:
[5, 6, 7, 1, 2, 3, 4]
Example 2:
Input:
nums = [-1, -100, 3, 99]
,k = 2
Output:
[3, 99, -1, -100]
The challenge here is to rotate the array in a way that minimizes both time complexity and space usage.
Approach 1: Naive Solution
The most intuitive solution is a brute force approach where we rotate the array by one position at a time k
times. However, this approach has a time complexity of O(n * k) and would not work efficiently for large arrays (when both n
and k
are near their maximum limits).
Approach 2: Using Extra Space (O(n) Space Complexity)
One simple way to solve this problem is by creating a new array and copying the elements in the rotated order. This would reduce the time complexity to O(n), but the space complexity would increase to O(n) because we would need to store the rotated array separately.
Here’s the basic idea for this approach:
Create a new array
result
of the same size asnums
.For each element in the original array, calculate its new position in the rotated array.
Copy the elements to their new positions.
#class Solution: uncomment if pasting in leetcode
def rotate(self, nums, k):
n = len(nums)
k = k % n # Handle cases where k is larger than n
result = [0] * n
# Rotate the elements and store them in the result array
for i in range(n):
new_position = (i + k) % n
result[new_position] = nums[i]
# Copy result back to nums
nums[:] = result
Time Complexity: O(n) because we iterate through the array once.
Space Complexity: O(n) because we use a separate array to store the rotated elements.
While this solution works, it does not meet the requirement to solve the problem using O(1) extra space. Let's move on to more efficient solutions.
Approach 3: Optimal In-Place Solution with O(1) Extra Space
To achieve O(1) extra space while maintaining O(n) time complexity, we can leverage the concept of array reversal. The idea is based on the observation that:
- Rotating an array to the right by
k
steps can be achieved by reversing different parts of the array.
Steps for In-Place Array Rotation
Reverse the entire array: This step puts the last
k
elements at the front, but in reverse order.Reverse the first
k
elements: This will put the lastk
elements in the correct order.Reverse the remaining
n-k
elements: This puts the firstn-k
elements in the correct order.
Implementation
#class Solution: uncomment if pasting in leetcode
def rotate(nums, k):
n = len(nums)
k = k % n # Handle cases where k is greater than n
# Step 1: Reverse the entire array
nums.reverse()
# Step 2: Reverse the first k elements and Reverse the remaining n-k elements
nums[:]=nums[-k:]+nums[:-k]
Explanation of Each Step
Reversing the entire array:
This step transforms the array from
[1, 2, 3, 4, 5, 6, 7]
to[7, 6, 5, 4, 3, 2, 1]
.At this point, the last
k
elements have been moved to the front, but in reverse order.
Reversing the first
k
elements:We now reverse the first
k
elements, so[7, 6, 5]
becomes[5, 6, 7]
.The array now looks like:
[5, 6, 7, 4, 3, 2, 1]
.
Reversing the remaining
n-k
elements:Finally, reverse the remaining
n-k
elements,[4, 3, 2, 1]
, to get[1, 2, 3, 4]
.The final rotated array is
[5, 6, 7, 1, 2, 3, 4]
.
Time and Space Complexity
Time Complexity: O(n) because reversing the array and the slices takes linear time.
Space Complexity: O(1) because we are modifying the array in place without using any extra space.
Why This Solution Works
The reason the reversal method works is that reversing the array changes the order of elements such that the last k
elements are placed at the front. After that, by reversing the individual segments, we restore the correct order for both parts of the array, resulting in the rotated array.
This solution not only meets the space constraint of O(1) but also runs efficiently with O(n) time complexity, making it optimal for large arrays.
Edge Cases to Consider
When
k
is 0:- If
k
is zero, the array remains unchanged. This is handled by the modulo operationk = k % n
.
- If
When
k
is greater than the length of the array:- By taking
k = k % n
, we ensure that the number of rotations is always within the bounds of the array length, so no extra work is needed for largek
.
- By taking
When
nums
has only one element:- A single-element array is trivially rotated by any number of steps, as it remains unchanged.
Conclusion
Array rotation is a common problem, and this blog post has explored different methods to rotate an array to the right by k
steps. We started with a naive approach that uses extra space, then moved on to the optimal in-place solution with O(1) extra space, using array reversal. This final solution is efficient, simple, and meets the constraints of the problem.
By understanding this method, you can solve the array rotation problem in interviews or competitive programming challenges with ease.
Further Reading
Left Rotation: The same technique can be adapted for rotating an array to the left. The concept remains similar, but the slices would be handled differently.
Circular Array Manipulation: Array rotation is just one example of circular array manipulation, which has many applications in problems like scheduling or sliding window algorithms.
Happy coding!