leetcode----31. Next Permutation

链接:

https://leetcode.com/problems/next-permutation/

大意:

给定一个排列(数组表示),按自然顺序找出其下一个排列(也是用数组表示)。如果找不到其下一个排列,则返回整个数组最小的排列(也不是真的返回,只是调整数组中各个元素的顺序)。还是看它给的例子吧:

思路:

第一步:从左往右,找到数组中最后出现的满足前一个大于后一个的数的位置index;

第二步:从index开始,一直到nums.length,找到比nums[index]大且是所有比nums[index]大的数中最小的数的位置minIdx;

第三步:交换nums[index]和num[minIdx],对数组nums在区间[index + 1,nums.length)的数进行排序   最后即可得到比给定序列大的最小序列了

其中,第一步和第二步在代码中可以放在一块执行(即不需要进行两次遍历)

代码:

class Solution {
    public void nextPermutation(int[] nums) {
        // 如果nums中元素个数为0或1 直接返回
        if (nums.length <= 1)
            return ;
        // 如果nums已经是一个非严格单调递减序列 则对nums按从小到大排序 return ;
        int i = 0, index = 0, minIdx = 0; // index为最后一个已知当前元素小于后一元素的当前元素的位置 minIdx为从index到nums.length中,比nums[index]的大的最小的数所在的位置
        boolean tag = true; // 用于记录nums是否为一个非严格递减序列
        while (i < nums.length - 1) {
            if (nums[i] < nums[i + 1]) { // 又找到了一个“递增序列”(相邻两元素)的起点
                index = i; 
                minIdx = i + 1;
                tag = false;
            } else if (nums[i + 1] < nums[minIdx] && nums[i + 1] > nums[index]) { // 对于之前找到的“递增序列”的起点,找到一个比nums[index]大并且比nums[minIdx]小的元素
                minIdx = i + 1;
            }
            i++;
        }
        // index == -1则表明在nums中,nums[i] >= nums[i+1] 即为非严格递减
        if (tag) {
            Arrays.sort(nums);
            return ;
        }
        // 最后只需将nums[index]和nums[minIdx]交换 并且对nums[index+1 ~ nums.length]按从小到大排序即可
        int t = nums[index];
        nums[index] = nums[minIdx];
        nums[minIdx] = t;
        Arrays.sort(nums, index + 1, nums.length);
    }
}

 结果:

结论:

有思路,就能解决。先想思路,再写代码

猜你喜欢

转载自blog.csdn.net/smart_ferry/article/details/88742322