LeetCode31. 下一个排列

实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须 原地 修改,只允许使用额外常数空间。

示例 1:

输入:nums = [1,2,3]
输出:[1,3,2]

示例 2:

输入:nums = [3,2,1]
输出:[1,2,3]

示例 3:

输入:nums = [1,1,5]
输出:[1,5,1]

示例 4:

输入:nums = [1]
输出:[1]

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

 

 

思路1:

  1. 首先从后向前找到`pre<cur`的位置`prePos`;(即:在从后向前的升序中查找第一个破坏升序的元素位置)
     1.1 若`prePos`值未改变,则整个数组反转,return
  2. 再次在`(pre, 数组长度-1]`从后向前查找`t>pre`的位置`tPos`;(即:在从后向前的升序中查找略大于pre的元素位置)
  3. `prePos`位置和`tPos`位置的元素进行交换
  4. 此时`(pre, 数组长度-1]`内的元素是降序,需进行反转,达到略大于原来值
    注意:在1中查找时可能数组是1234,需整个反转

refer: https://leetcode-cn.com/problems/next-permutation/solution/31-xia-yi-ge-pai-lie-by-qquser-2-jdbj/

具体代码:

class Solution {
    public void nextPermutation(int[] nums) {
        int n = nums.length;
        int idx1 = -1;
        for (int i=n-1; i>0; i--) {
            if (nums[i] > nums[i-1]) {
                idx1 = i - 1;
                break ;
            }
        }

        if (idx1 == -1) {
            reverse(nums, 0, n - 1);
            return ;
        }

        int idx2 = -1;
        for (int i=n-1; i>idx1; i--) {
            if (nums[i] > nums[idx1]) {
                idx2 = i;
                break ;
            }
        }
        swap(nums, idx1, idx2);
        reverse(nums, idx1 + 1, n - 1);
    }
    public void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    public void reverse(int[] nums, int i, int j) {
        while (i < j) {
            swap(nums, i, j);
            i++;
            j--;
        }
    }
}

 

 

 

LeetCode31. 下一个排列

上一篇:REDIS集群脑裂以及解决方案


下一篇:Spring的配置文件applicationContext.xml