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

题目理解:

给定一个字符向量,对其进行操作,变成比它字典序大一个单位的新序列;如果原字典序已经是最大了,那么就变成其最小字典序的序列。


解题思路:

因为要找上一级字典序,所以首要的是将后面大的元素提到前面去,但由于我们所求的只是上“一”级,因此,不能直接调换,具体算法流程如下:

  1. 首先,从后向前遍历,找到第一个比自己之前的元素大的位置,将start设置在较小元素的位置上,并记录最小元素值。若找不到,则将原向量升序排列。
  2. 然后从较大元素的位置开始,向后遍历,找到与刚才记录的最小元素值相差最小的元素(为了保证只升一级),将其与最小元素进行调换。
  3. 为了真正的只升一级,还需要将更新的start位置后面的元素,按照升序排列,这样才可以将内容值提升做到最小。

代码:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        //给的例子长度太小,看不出规律来,这时应该自己举例找规律。。。
        int start = -1,end = -1;
        int base = -1;
        for(int i=nums.size()-1;i>0;i--){
            if(nums[i]>nums[i-1]){
                start = i-1;
                base = nums[i-1];
                break;
            }
        }
        if(start == -1){
            sort(nums.begin(),nums.end());
            return;
        }
        int minN = INT_MAX;
        for(int i=start+1;i<nums.size();i++){
            if(nums[i]>base){
                int tmp = nums[i] - base;
                if(tmp < minN){
                    minN = tmp;
                    end = i;
                }
            }
        }
        //exchange
        int tmp = nums[end];
        nums[end] = nums[start];
        nums[start] = tmp;
        
        //reverse the remained
        sort(nums.begin()+start+1,nums.end());
    }
};

总结:

不得不承认,如果单词不认识的话,单看样例是理解不了这个题的意思的,也间接告诉了自己不能偷懒不读题,而是通过样例去理解题意,这样是片面的,不正确的。
我通过样例想出的解题方法太不全面,看了solution之后立马就明白了,是什么意思,仅仅是因为例子变长了一些,然后通过这个变长的例子再进行思考就可以得出结论。
因此,以后做题的时候,一定要读懂题,然后想明白题的意思与要求,再去看例子,不懂是编不出来题的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值