Similar to next permutation, the steps as follow:
1) Find k in the increasing suffix such that nums[k] > nums[k+1], if there is no such element, the permutation is the smallest like [0, 1, 2,... n], reverse it, we can get the previous permutaton.
2) Find the largest element in the increasing suffix which is smaller than nums[k], nums[p] < nums[k] ( p in [k+1, nums.size()), swap nums[k] with nums[p]
3) Since the suffix remains decreasing, which is the smallest suffix, instead we are looking for largest suffix, we can achieve this by reversing the suffix.
Time complexity: O(n), Space complexity: O(1)
public class PreviousP { private int findLargestNumSmallerThanK(List<Integer> nums, int k) { for(int i = nums.size()-1; i > k; --i) { if(nums.get(i) < nums.get(k)) return i; } return -1; } public List<Integer> previousP(List<Integer> nums) { int size = nums.size(); int k = size - 2; while(k >= 0 && nums.get(k) <= nums.get(k+1)) { --k; } if(k != -1) { int p = findLargestNumSmallerThanK(nums, k); Collections.swap(nums, k, p); } Collections.reverse(nums.subList(k+1, size)); return nums; } public static void main(String[] args) { PreviousP p = new PreviousP(); System.out.println(p.previousP(Arrays.asList(6, 2, 3, 1, 4, 5)).toString().equals("[6, 2, 1, 5, 4, 3")); } }