A permutation of an array of integers is an arrangement of its members into a sequence or linear order.
arr = [1,2,3]
, the following are all the permutations of arr
: [1,2,3], [1,3,2], [2, 1, 3], [2, 3, 1], [3,1,2], [3,2,1]
.The next permutation of an array of integers is the next lexicographically greater permutation of its integer. More formally, if all the permutations of the array are sorted in one container according to their lexicographical order, then the next permutation of that array is the permutation that follows it in the sorted container. If such arrangement is not possible, the array must be rearranged as the lowest possible order (i.e., sorted in ascending order).
arr = [1,2,3]
is [1,3,2]
.arr = [2,3,1]
is [3,1,2]
.arr = [3,2,1]
is [1,2,3]
because [3,2,1]
does not have a lexicographical larger rearrangement.Given an array of integers nums
, find the next permutation of nums
.
The replacement must be in place and use only constant extra memory.
Example 1:
Input: nums = [1,2,3]
Output: [1,3,2]
Example 2:
Input: nums = [3,2,1]
Output: [1,2,3]
Example 3:
Input: nums = [1,1,5]
Output: [1,5,1]
Given an array of integers nums
, the goal is to find the next permutation of nums
in lexicographical order. If no such permutation exists, rearrange the array in ascending order. This must be done in-place with constant extra memory.
The most straightforward approach would be to generate all possible permutations of the array, sort them lexicographically, and then find the next permutation after the given input array. However, this is highly inefficient.
nums
. This can be done recursively.nums
within the sorted list of permutations.nums
is the last element, return the first permutation.import itertools
def next_permutation_naive(nums):
permutations = sorted(list(itertools.permutations(nums)))
for i in range(len(permutations)):
if permutations[i] == tuple(nums):
return list(permutations[(i + 1) % len(permutations)])
This approach has a time complexity of O(n! * n log n) due to generating all permutations and sorting them. This is not efficient for larger arrays.
The optimal approach involves a few key steps to find the next permutation in-place:
i
where nums[i] < nums[i+1]
. If no such index exists, the array is in descending order, and we need to reverse it to get the smallest permutation.i
that is greater than nums[i]
: Search the subarray to the right of i
to find the smallest element nums[j]
that is greater than nums[i]
.nums[i]
and nums[j]
: Exchange these two elements.i
: This ensures that the subarray is in ascending order, making the overall permutation the next lexicographical permutation.def next_permutation(nums):
n = len(nums)
# Step 1: Find the first decreasing element from the right
i = n - 2
while i >= 0 and nums[i] >= nums[i + 1]:
i -= 1
if i >= 0:
# Step 2: Find the smallest element to the right of i that is greater than nums[i]
j = n - 1
while nums[j] <= nums[i]:
j -= 1
# Step 3: Swap nums[i] and nums[j]
nums[i], nums[j] = nums[j], nums[i]
# Step 4: Reverse the subarray to the right of i
left = i + 1
right = n - 1
while left < right>0:
return 0
Consider the array nums = [1, 2, 3]
. Here's how the algorithm would proceed:
i
starts at n - 2 = 1
. nums[1] < nums[2]
(2 < 3), so i
remains 1.j
starts at n - 1 = 2
. nums[2] > nums[1]
(3 > 2), so j
remains 2.nums[1]
and nums[2]
: nums
becomes [1, 3, 2]
.i
(which is just nums[2]
): No change needed.The result is [1, 3, 2]
, which is the next permutation.
Now consider nums = [3, 2, 1]
.
i
starts at n - 2 = 1
. nums[1] >= nums[2]
(2 >= 1), so i
becomes 0. nums[0] >= nums[1]
(3 >= 2), so i
becomes -1.i < 0
, reverse the entire array. The result is [1, 2, 3]
.