31. Next Permutation

class Solution {
    void swap(int []nums, int i, int j)
    {
        int t=nums[i];
        nums[i]=nums[j];
        nums[j]=t;
    }
    
    void swapWithGreater(int []nums, int i)
    {
        for(int j=nums.length-1;j>i;--j)
        {
            if(nums[j]>nums[i])
            {
                swap(nums,i,j);
                return;
            }
        }
    }
    
    void reverse(int []nums, int i)
    {
        int last=nums.length-1;
        while(i<last)
        {
            swap(nums,i,last);
            ++i;
            --last;
        }
    }
    public void nextPermutation(int[] nums) {
        if(nums.length<2)return;
        int i=nums.length-1;
        for(;i>0;--i)//从数组最右边往最左边检测,每次检测相邻的两个数i-1和i,找到i-1小于i的情况
        {
            if(nums[i-1]<nums[i])break;
        }
        
        if(i!=0)
            swapWithGreater(nums,i-1);//从最右边的元素到i为止的这段区间,从最右边的元素开始往左查找,找到一个比i-1大的元素进行交换
        reverse(nums,i);//i到最右边的这段范围进行反转处理
    }
}

参考答案写的;

基本思路,按字典顺序排除下一个组合,就是把右边较大的元素和左边某个位置交换。想象一下000一直变大到999的过程,是不是总是先从个位数变大直到进位,再由十位数变大?

这个过程类似但不一样。000到999用到了多少个数字?permutation这里可没有那么多。因此不能简单的加1处理。

原文地址:https://www.cnblogs.com/lychnis/p/10667834.html