31. Next Permutation

这类题目多数都需要多用些例子找出规律,结合自己的分析和猜测不断去验证自己规律的正确性,如果没有例子,很难看懂别人写的最优解的代码。

这道题目的规律是:从后往前扫描,找到不满足num[i-1]>=num[i]的第一个数,然后此位置之前的从后往前扫面第一个大于此数字的数交换位置,第三步是对交换位置的后半部分进行reverse操作。

这道题目我自己的解法是交换位置后对后面的数字进行了重新排序,此种情况下最坏的时间复杂的为O(nlgn).

代码如下:

class Solution {
    public void nextPermutation(int[] nums) {
        int len=nums.length;
        int max=nums[len-1];
        for(int i=len-2;i>=0;i--){
            if(max<nums[i]){
                max=nums[i];
            }else if(nums[i]<max){
                for(int j=len-1;j>=i;j--){
                    if(nums[j]>nums[i]){
                        int temp=nums[j];
                        nums[j]=nums[i];
                        nums[i]=temp;
                        Arrays.sort(nums,i+1,len);
                        return ;
                    }
                }
            }
        }
        Arrays.sort(nums);
    }
}

最优解应该是:

class Solution {
    public void nextPermutation(int[] nums) {
       int len=nums.length-1;
        int i=len,index=-1;
        while(i>0){
            if(nums[i]>nums[i-1]){
                index=i-1;
                break;
            }else
                i--;
        }
        if(index!=-1){
            i=len;
            while(i>index){
                if(nums[i]>nums[index]){
                    swap(nums,i,index);
                    break;
                }else
                    i--;
            }
        }
        index++;
        i=len;
        while(index<i){
            swap(nums,index,i);
            i--;
            index++;
        }
    }
    
    public void swap(int num[],int i,int j){
        if(i!=j){
            num[i]^=num[j];
            num[j]^=num[i];
            num[i]^=num[j];
        }
    }
}

 

总结:对于规律总结的不是很透彻,在于数据案例不够多,多列举一些例子对寻找最优解会有帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值