Next Permutation of Array in DSA Python - Time & Space Complexity
We want to understand how the time needed to find the next permutation changes as the array size grows.
Specifically, how many steps does the algorithm take when the array gets bigger?
Analyze the time complexity of the following code snippet.
def next_permutation(nums):
i = len(nums) - 2
while i >= 0 and nums[i] >= nums[i + 1]:
i -= 1
if i >= 0:
j = len(nums) - 1
while nums[j] <= nums[i]:
j -= 1
nums[i], nums[j] = nums[j], nums[i]
nums[i + 1:] = reversed(nums[i + 1:])
This code finds the next lexicographical permutation of the input list of numbers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Two while loops scanning parts of the array and one slice reversal.
- How many times: Each loop runs at most once from the end towards the start, scanning up to n elements.
As the array size grows, the loops and reversal may scan more elements, but each step still goes through the array at most once.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to about 30 steps |
| 100 | Up to about 300 steps |
| 1000 | Up to about 3000 steps |
Pattern observation: The number of steps grows roughly in direct proportion to the input size.
Time Complexity: O(n)
This means the time to find the next permutation grows linearly with the size of the array.
[X] Wrong: "The algorithm checks all possible permutations, so it must be factorial time."
[OK] Correct: The algorithm smartly finds the next permutation by scanning the array only a few times, not generating all permutations.
Understanding this linear time approach shows you can handle array manipulation efficiently, a skill often needed in real coding problems.
"What if the input array is already the highest permutation? How does that affect the time complexity?"
Practice
next permutation of an array represent?Solution
Step 1: Understand the concept of permutation order
Permutations can be ordered lexicographically like words in a dictionary.Step 2: Define next permutation meaning
The next permutation is the next arrangement that is just greater than the current one in this order.Final Answer:
The next lexicographically greater arrangement of the array elements -> Option AQuick Check:
Next permutation = next bigger arrangement [OK]
- Thinking next permutation is just sorting ascending
- Confusing next permutation with reversing the array
- Assuming next permutation always moves smallest element front
arr[i] and arr[j] in an array?Solution
Step 1: Recall Python tuple unpacking for swapping
Python allows swapping two variables in one line using tuple unpacking.Step 2: Check each option
arr[i], arr[j] = arr[j], arr[i] correctly swaps usingarr[i], arr[j] = arr[j], arr[i]. arr[i] = arr[j]; arr[j] = arr[i] overwritesarr[i]before assigningarr[j]. swap(arr[i], arr[j]) is invalid syntax without a defined function. arr[i] = arr[j] only assigns one element.Final Answer:
arr[i], arr[j] = arr[j], arr[i] -> Option AQuick Check:
Python swap uses tuple unpacking [OK]
- Overwriting one element before swapping
- Using undefined swap function
- Assigning only one element instead of both
arr = [1, 3, 2] # Apply next permutation logic # Step 1: Find first decreasing element from right (index 0) # Step 2: Find element just larger than arr[0] from right (index 2) # Step 3: Swap arr[0] and arr[2] # Step 4: Reverse elements after index 0 arr[0], arr[2] = arr[2], arr[0] arr[1:] = arr[1:][::-1] print(arr)
Solution
Step 1: Identify the first decreasing element from right
From right, arr[1]=3 > arr[2]=2 (not decreasing), arr[0]=1 < arr[1]=3 (decreasing at index 0)Step 2: Find element just larger than arr[0] from right
From right, arr[2]=2 > arr[0]=1, so index 2 chosenStep 3: Swap arr[0] and arr[2]
Swap 1 and 2 -> arr becomes [2, 3, 1]Step 4: Reverse elements after index 0
Reverse arr[1:] -> arr[1:] = [3,1] reversed to [1,3]Final Answer:
[2, 1, 3] -> Option BQuick Check:
Next permutation of [1,3,2] = [2,1,3] [OK]
- Not reversing suffix after swap
- Swapping wrong elements
- Confusing increasing and decreasing order
arr = [3, 2, 1]. What is the error?def next_permutation(arr):
i = len(arr) - 2
while i >= 0 and arr[i] >= arr[i + 1]:
i -= 1
if i >= 0:
j = len(arr) - 1
while arr[j] <= arr[i]:
j -= 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1:] = reversed(arr[i + 1:])
arr = [3, 2, 1]
next_permutation(arr)
print(arr)Solution
Step 1: Analyze the reversal line
The linearr[i + 1:] = reversed(arr[i + 1:])assigns an iterator to a list slice, which expects a list.Step 2: Identify correct usage
To assign reversed elements properly, convert iterator to list:arr[i + 1:] = list(reversed(arr[i + 1:])).Final Answer:
Using reversed() returns an iterator, not a list, causing wrong assignment -> Option CQuick Check:
reversed() needs list() for slice assignment [OK]
- Assigning reversed() iterator directly to list slice
- Ignoring empty array edge case
- Swapping elements incorrectly
arr = [1, 5, 1], what is the next permutation after applying the standard algorithm? Consider duplicates carefully.Solution
Step 1: Find first decreasing element from right
From right: arr[1]=5 > arr[2]=1 (not decreasing), arr[0]=1 < arr[1]=5 (decreasing at index 0)Step 2: Find element just larger than arr[0] from right
From right, arr[2]=1 not > 1, arr[1]=5 > 1, so index 1 chosenStep 3: Swap arr[0] and arr[1]
Swap 1 and 5 -> arr becomes [5, 1, 1]Step 4: Reverse elements after index 0
Reverse arr[1:] -> arr[1:] = [1,1] reversed is same [1,1]Final Answer:
[5, 1, 1] -> Option DQuick Check:
Duplicates handled, next permutation = [5,1,1] [OK]
- Ignoring duplicates when finding next bigger element
- Not reversing suffix after swap
- Assuming next permutation is sorted ascending always
Ready to prove it?
Pass the test and this pattern moves unknown
