[leetcode] 31. 下一个排列

31. 下一个排列

发现规律后很简单:

下一个排列即是要找字典序中下一个更大的排列。

如串s:1 2 3 6 5 4 2 的下一个排列是 1 2 4 2 3 5 6

我们将数字串头点即为a,尾点记作b,从右往左看找到第一个降序数字的位置记为p,如例:

1236542
a_p___b

在s[p+1~b]子串中找到>s[p]的最小点,然后与s[p]交换:

1246532
a_p___b

此时,s[p+1~b]肯定仍然满足降序排列(从右往左看是升序),然后将s[p+1~b]做下reverse即可

1242356
a_p___b

当p找不到,或p的位置<a时,则将数字重新排列成最小的排列,即整条串做个reverse即可

class Solution {
    public void nextPermutation(int[] nums) {
        if (nums.length == 1) {
            return;
        }
        int p = -1;
        for (int i = nums.length - 2; i >= 0; i--) {
            if (nums[i] < nums[i + 1]) {
                p = i;
                break;
            }
        }

        if (p != -1) {
            int tmp = nums[p];
            int q = nums.length - 1;
            while (nums[q] <= tmp) {
                q--;
            }
            nums[p] = nums[q];
            nums[q] = tmp;

            reverse(p + 1, nums);
        } else {
            reverse(0, nums);
        }
    }


    public void reverse(int k, int[] nums) {
        if (k >= nums.length) return;
        int i = k;
        int j = nums.length - 1;
        while (i < j) {
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
            i++;
            j--;
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/acbingo/p/9297372.html