LeetCode (31)Next Permutation

31 篇文章 0 订阅

(31)Next Permutation

题目:找到比目标数大的,只使用目标数内数字组成的最小的数。如果这种安排是不可能的,它必须重新安排它作为最低可能的顺序(即按升序排序)。更换必须到位,不要分配额外内存。

例如:

1,2,3 -> 1,3,2
3,2,1 -> 1,2,3
1,1,5 -> 1,5,1

自己推算几次,找几个例子,就能有一个比较好的想法了。

首先对于比这个数大的最小数,那么就是从最后位开始向前找,当找到下一个数字比当前数字小的时候,那么就从这一位往后直到末位,在这些里面进行变换,先说一下变换方式,方式是:首先从后先前找到前一个数字比后一个数字小的数字,为nums[top],在top直至nums.end()之间找到比num[top]大的最小数字num[next],将两个数字调换,然后将top+1直到nums.end()间的数字做排序,小数字在前大数字在后,就获得了目标数。

这里我举一个例子,假如数是“1234651”,那么由于从后向前查找的过程中,第一次前一个数字比后一个小的情况是“4”比“6”小,那么就是在“4651”这几个数字里面进行变换,问题变成找到能比“4651”大的第一个数,首位为“4”,后面的各个数字中比“4”大的最小数字是“5”(由于在“651”里面比“4”大的最小数字是“5”),那么把这两个数字调换位置,“4651”变成了“5641”,将“641”进行排序,小数字在前,大数字在后,获得“146“,这样就获得了目标数“1235146”。

但要注意一个问题,如果整个数字原本就是从大到小的一个序列,比如“654321”,那么通过搜索找不到top的位置,此时top为-1,那么就是直接全体排序。

下面是代码:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int top,len = nums.size();
        if(len == 1||len == 0){
            return ;
        }
        int temp = nums[len-1];
        int i = 0;
        for(i = len - 2; i >= 0; i --){
            if(temp > nums[i]){
                top = i;
                break;
            }
            else{
                temp = nums[i];
            }
        }
        if(i<0){
            vector<int>::iterator left = nums.begin(), right = nums.end();
            sort(left , right);
            return;
        }
        temp = nums[i];
        int next = nums[i + 1], num = i + 1;
        for( i = i + 1; i <= len - 1; i ++ ){
            if(nums[i] > temp){
                if(nums[i] < next){
                    next = nums[i];
                    num = i;
                }
            }
        }
        nums[num] = temp;
        nums[top] = next;
        vector<int>::iterator left = nums.begin()+top+1, right = nums.end();
        sort(left , right);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值