31 Next Permutation

说实话,看到这题完全懵逼。。。不知道当时是怎么写出来的。。。而且我今天一口气,3个小时写了12道题,大脑已经停止运转了。。。先把代码贴上,晚点再来搞定!


import java.util.Arrays;

public class Solution {
    public void nextPermutation(int[] nums) {
        if(nums==null || nums.length==0) return;
            
        int i;
        for(i=nums.length-1; i>0; i--){  // iterate from right to left, expect to see increasing or equals
            // find the position with unexpected increasing trend, another number to be swapped. If found, do the swap immediately
            if(nums[i-1]<nums[i]){// when left is smaller, we find target, which is nums[i-1];
                
                // find the minLarger (the smallest number bigger than [i-1]) on the right side, which will be swapped
                int minLarger=nums[i]; // at least [i] is larger than [i-1]
                int tag=i;
                for(int j=i; j<nums.length; j++){            
                    if(nums[j]<minLarger && nums[j]>nums[i-1]){  // typical code block to find the mins: update min (of course) and index
                        tag=j;
                        minLarger=nums[j];
                    }                
                }
                
                // swap without extra space !!! useful trick
                nums[i-1]=nums[i-1]^nums[tag];
                nums[tag]=nums[i-1]^nums[tag];
                nums[i-1]=nums[i-1]^nums[tag];
                
                // sort from [i] to the rest;
                Arrays.sort(nums, i, nums.length); // Arrays.sort(array, start, end);  start is inclusive, end is exclusive, so nums.length is valid  
                return;
            }
        }
        
        // if not return previously, it means that the array is the larget, so return the smallest;
        Arrays.sort(nums);  // default form, sort the whole array;
        return ;
            
    }
}

今天的代码,是参考了code ganker的思路,然后来实现的,非常的make sense啊!从后往前找以第一个降序的位置,降序就说明该位置后面的数字升序排列到头了,下一个位置是要换一个较大的数字,然后之后的所有数字进行升序排列,然后就得到下一个数字。。

public class Solution {
    public void nextPermutation(int[] nums) {
        int len= nums.length;
        if(len==0) return;
        int i=len-2;
        for(; i>=0; i--){
            if(nums[i]<nums[i+1]) break; // 不能等于,比如5 1 1 这个数
        }
        if(i>=0){  // i can be -1, then reverse the whole nums
            int j=i+1; // 我去,line16的bug在这里找到,我以为j=i没什么问题,其实不行,因为看下面for中break的条件,那么就j=i就停了!
            for(; j<len; j++){
                if(nums[j]<=nums[i]) break; // 这个地方可以==,因为--后就肯定是大于的
            } //有可能不会break,而是到底了,j=len,那也没关系,因为目标是j--;
            j--;
            int tmp=nums[i];
            nums[i]=nums[j];
            nums[j]=tmp;
        }
        Arrays.sort(nums, i+1, len);
        //reverse(nums, i+1); // 其实有自带的方法来完成reverse的步骤,Arrays.sort(nums, i+1, len) 即可,如上
    }
    
/*    private void reverse(int[] nums, int index){
        int left=index;
        int right=nums.length-1;
        while(left<right){
            int tmp=nums[left];
            nums[left]=nums[right];
            nums[right]=tmp;            
            left++;
            right--;
        }
    }*/
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值