Previous Permutation
Given a list of integers, which denote a permutation.
Find the previous permutation in ascending order.
The list may contains duplicate integers.
Example:
For [1,3,2,3], the previous permutation is [1,2,3,3]
For [1,2,3,4], the previous permutation is [4,3,2,1]
Solution:
Similar idea to Next Permutation, but we do it reversely.
Assume we have [1,2,7,1,2,3,6]:
- We first find the first decreasing trend from the right of the list ( 7 and 1), we choose the index 3 (value is 1).
- We reverse the elements from index 3 to the end: [1,2,7,1,2,3,6] => [1,2,7,6,3,2,1]
- If we couldn't find the decreasing trend in step one, we can skip step 3. We may have [1,2,3,4] => [4,3,2,1]
- We find the first number from index 3 (value is 6 now), where this number should be smaller than the index 2 (value 7) from step 1. Then we swap them: [1,2,7,6,3,2,1] => [1,2,6,7,3,2,1]
Code:
public class Solution {
public ArrayList<Integer> previousPermuation(ArrayList<Integer> nums) {
if (nums == null || nums.size() <= 1) {
return nums;
}
int i = nums.size() - 1;
while (i > 0 && nums.get(i) >= nums.get(i - 1)) {
i--;
}
reverse(nums, i, nums.size() - 1);
if (i == 0) {
return nums;
}
int j = i;
while (nums.get(j) >= nums.get(i - 1)) {
j++;
}
swap(nums, j, i - 1);
return nums;
}
private void reverse(List<Integer> nums, int left, int right) {
for (; left < right; left++, right--) {
swap(nums, left, right);
}
}
private void swap(List<Integer> nums, int a, int b) {
int temp = nums.get(a);
nums.set(a, nums.get(b));
nums.set(b, temp);
}
}