zoukankan      html  css  js  c++  java
  • 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 存在,如果还执行到这儿,说明数字已经达到最大,重排一下即可
        }
    }
  • 相关阅读:
    诗人就是“情场浪子”的代名词?
    微博营销,开启营销的新时代
    网店成功之道:卖家应有4种心态(实战交流)
    一枚钉子前进
    推动中国文学的发展,我义不容辞
    微博营销,再次引爆网络江湖
    微博营销,不仅仅是粉丝
    邮件群发软件版本升级公告
    如何让自己在浩瀚的网海中脱颖而出
    如何定时关机【windows/linux】
  • 原文地址:https://www.cnblogs.com/luo-c/p/12923603.html
Copyright © 2011-2022 走看看