LeetCode 31. Next Permutation

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place and use only constant extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

找到下一个大的组合。

这里直接给出LeetCode上的解法,据说是14世纪的算法...

具体写起来的话很简单:

需要仔细理解下面的注释

    // Find the largest index k such that nums[k] < nums[k + 1]  If no such index exists, just reverse nums and done
    //nums[0:k-1]是nums和next permutation的公共部分
    // Find the largest index l > k such that nums[k] < nums[l]
    // Swap nums[k] and nums[l]
    //现在nums[0:k-1]后面是nums[l],而nums[0:k-1]串上nums[l]就是next permutation的开头部分
    // Reverse the sub-array nums[k + 1:]  剩下的这部分逆序之后就走向了nums[0:k-1]串nums[l]的子树的最左分支(最小分支)
    public void nextPermutation(int[] nums) {
    	int n = nums.length;
        int k;
        int l;
    	for(k = n - 2; k >= 0; k--) {
            if(nums[k] < nums[k + 1]) {
                break;
            }
        }
    	if(k < 0){//不存在使得nums[k]>nums[k+1]的k
    	    reverseFrom(nums,0);
    	} 
        else{
    	    for(l = n - 1; l > k; l--) {
                if(nums[l] > nums[k]) {
                    break;
                }
            } 
            //能找到k的话, l一定存在
    	    swap(nums,k,l);
    	    reverseFrom(nums,k + 1);
        }
    }
    private void reverseFrom(int[] nums,int start){
        int i = start;
        int j = nums.length-1;
        while(i<j){
            swap(nums,i,j);
            i++;
            j--;
        }
        return;
    }
    private void swap(int[] nums,int i,int j){
        int t = nums[i];
        nums[i] = nums[j];
        nums[j] = t;
        return;
    } 

看下面这个例子,1243的next permutation是1324

第一步,k=1

第二步,  l=3 

第三步,交换nums[k]和nums[l],nums变为1342

第四步,k+1=2,将nums[2:]逆序,得到nums为1324

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值