LeetCode 热题100-15-下一个排列

核心思想:双指针

如何判断按照字典序有没有下一个,如果完全降序就没有下一个;
如何判断有没有下一个呢?只要存在a[i] < a[i+1]的升序结构,就有,而且我们应该从右往左找,一旦找到,因为这样才是真正下一个;
当发现a[i] < a[i+1]的结构时,从在[i+1,len)中找到最接近a[i]并且又大于a[i]的数字,由于降序,从右往左遍历即可得到k,然后交换a[i]与a[k],然后对[i+1,len)排序即可,排序只需要首尾不停交换即可。
思路:希望下一个数增加的幅度尽可能的小,这样才满足“下一个排列与当前排列紧邻“的要求。为了满足这个要求,需要:
(1)在尽可能靠右的低位进行交换,需要从后向前查找;
(2)将一个 尽可能小的「大数」 与前面的「小数」交换。比如 123465,下一个排列应该把 5 和 4 交换而不是把 6 和 4 交换;
(3)将「大数」换到前面后,需要将「大数」后面的所有数重置为升序,升序排列就是最小的排列。

class Solution {
    public void nextPermutation(int[] nums) {
        int left,right;
        int len = nums.length;
        right = len - 2;
        //寻找a[i] < a[i+1]
        while(right >= 0){
            if(nums[right] < nums[right + 1]){
                break;
            }
            right--;
        }
        left = right;
        right = len - 1;
        //寻找最接近的数
        while(right >= 0 && left >= 0){
            if(nums[right] > nums[left]){
                break;
            }
            right--;
        }
        int i;
        //交换
        if(left >= 0){
            i = nums[left];
            nums[left] = nums[right];
            nums[right] = i;
        }
        //排序输出
        for(int j = 1; j <= (nums.length - left) / 2; j++){
            i = nums[j + left];
            nums[j + left] = nums[--len];
            nums[len] = i;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值