31.Next Permutation


给定一个数组,将里面的数字找到比当前排列大一个的下一个排列。如果找不到,则返回最小值排列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

注意:是找比当前排列大的下一个排列,并不是找最大的排列。

思路:
规律还是比较好找的,从后往前看,如果是:54321. 这种表示已经是最大排列了,因为前面一个数都比后面一个数大,不管怎么换,所组成的排列都比当前的数小。而只有 54231,这种,后面的3有比前面的2大,将大的数字换过来,整体排列就变大了。所以,关键在于从后往前看,找到第一个前面比后面小的数,然后,从后面的数里面选一个比当前位置的数大的交换,然后将后面的数字从小到大排列
比如: 12543, 2比5小,然后在后面的543中找一个比2大的数交换,找到了3,变成13542,最后再将542从小到大排列,即为:13245。即,13245是比12543大的下一个排列。

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int n = nums.size(), r = n - 1;
        for (int i = n - 1; i > 0; i--) {
            if (nums[i - 1] >= nums[i]) continue;
            else {  //寻找位置
                while (r > i - 1) {
                    if (nums[i - 1] < nums[r]) { //再后面寻找比当前大的数交换
                        int tmp = nums[i - 1];
                        nums[i - 1] = nums[r];
                        nums[r] = tmp;
                        break;
                    }
                    else r--;
                }
                minToMax(nums, i, n - 1);//后面剩余的从小到大排列
                return;
            }
        }
        minToMax(nums, 0, n - 1);
    }

    void minToMax(vector<int>& nums, int left, int right) { // 从小到大交换
        int n = right - left + 1, tmp = 0;
        for (int i = 0; i < n / 2; i++) {
            tmp = nums[i + left];
            nums[i + left] = nums[right - i];
            nums[right - i] = tmp;
        }
    }
};

 

Java 版:

class Solution {
    public void nextPermutation(int[] nums) {
        for(int i = nums.length - 1; i > 0; i--){
            if(nums[i] > nums[i-1]){
                for(int j = nums.length - 1; j >= i ; j--){ // 要注意这儿 j >= i
                    if(nums[j] > nums[i-1]){
                        int tmp = nums[i-1]; //交换数字
                        nums[i-1] = nums[j];
                        nums[j] = tmp;
                        Arrays.sort(nums,i,nums.length); // 对后面的数字按升序重排列
                        return; //直接退出
                    }
                }
            }
        }
        Arrays.sort(nums); //因为有上面的 return 存在,如果还执行到这儿,说明数字已经达到最大,重排一下即可
    }
}

 

posted @ 2020-05-20 14:52  星海寻梦233  阅读(157)  评论(0编辑  收藏  举报