Next Permutation

Given a list of integers, which denote a permutation.

Find the next permutation in ascending order.

Example

For [1,3,2,3], the next permutation is [1,3,3,2] For [4,3,2,1], the next permutation is [1,2,3,4]

Note

The list may contains duplicate integers.

Think

字典序算法:

  • 从后往前寻找索引满足 a[k] < a[k + 1], 如果此条件不满足,则说明已遍历到最后一个。
  • 如 k == 0, 说明是字典序最后一位, 因此直接倒置整个数组即可.
  • 从后往前遍历,找到第一个比a[k]大的数a[l], 即a[k] < a[l].
  • 交换a[k]与a[l].
  • 反转k + 1 ~ n之间的元素.

Solution

public class Solution {
    /**
     * @param nums: an array of integers
     * @return: return nothing (void), do not return anything, modify nums in-place instead
     */
    public int[] nextPermutation(int[] nums) {
        if(nums == null || nums.length == 1)
            return nums;

        // step1: find nums[i] < nums[i + 1]
        int i = 0;
        for (i = nums.length - 2; i >= 0; i--) {
            if (nums[i] < nums[i + 1]) {
                break;
            } else if (i == 0) {
                // reverse nums if reach maximum
                reverse(nums, 0, nums.length - 1);
                return nums;
            }
        }
        // step2: find nums[i] < nums[j]
        int j = 0;
        for (j = nums.length - 1; j > i; j--) {
            if (nums[i] < nums[j]) {
                break;
            }
        }
        // step3: swap betwenn nums[i] and nums[j]
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;

        // step4: reverse between [i + 1, n - 1]
        reverse(nums, i + 1, nums.length - 1);

        return nums;
    }

    private void reverse(int[] nums, int l, int r) {
        while(l < r) {
            int tmp = nums[l];
            nums[l++] = nums[r];
            nums[r--] = tmp;
        }
    }
}

Complexity Analysis

At most, two pass o(2*n) -> O(n); Constant Space Complexity: O(1)

results matching ""

    No results matching ""