2021-05-12Leetcode31.下一个排列

在这里插入图片描述
1.1关于题目的理解
将整个数组看成是一个数字
以三个数字1、2、3为例,从小到大一所能够组成的所有的数字为123、132、213、231、312、321
让这些数字按照这个顺序循环出现,找到目前所给的循环中的下一个数字是什么。

1.2我的解法
1)用单调栈,单调栈的目的是找到第一个比某个数字最大/最小的数字
2)将第一个比前面小的数字和单调栈中第一个比其略大的数字互相交换
3)然后将这两个数字中间所有的数字从前往后升序排列统一移动到后面,(移动是不少的时间开销)

1.3优化
直接将2)中的两个数字对换,然后后面其余的数字之直接升序排列

我的代码:

void nextPermutation(vector<int>& nums) {
        int i,p;
        stack<int> mystack;
        bool find = false;
        for(i = nums.size() - 1;i >= 0 ;i--){
            while(!mystack.empty() &&nums[i] < nums[mystack.top()]){
                p = mystack.top();
                mystack.pop();
                find = true;
            }//单调栈,找到第一个从后降序的数字
            //但是用单调栈不好,额外开辟了空间,并且本质上任然是相邻两个数字的比较
            if(find)  break;
            else mystack.push(i);
        }
        if(mystack.size() == nums.size()){
            sort(nums.begin(),nums.end());
        }//如果从头到尾都是降序,那就改成升序
        else if(p - i == 1){//p是较大的下标
            int temp = nums[i];
            nums[i] = nums[p];
            nums[p] = temp;
        }
        else {
            int temp = nums[p];
            sort(nums.begin()+i+1,nums.begin()+p-1);//如果sort中间这一段数据为空返回的是什么?
            for(int j = 0 ; j < p - i;j++){
                nums[i+j+1] = nums[i+j];
            }//顺便把p向后移动的同时将
            nums[i] = temp;
        }
    }

比较好的代码

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int i = nums.size()-1;
        if (i == 0) return;
        //我的欠缺点之一:没有考虑到数组的长度不够的情况
        //if(i<=1) return;其实更好
        while (i>=1&&nums[i-1]>=nums[i])i--;
        //和前一个数字比较,只用一个参数,节约空间
        if (i == 0) {
            reverse(nums.begin(),nums.end());
            return;//直接返回是可以的
        }
        
        i = i-1;//其实i-1才是那个第一个比较小的数字的数字
        int j = nums.size()-1;
        while (nums[j]<=nums[i]) j--;//从后面那堆降序的数字中找到比较小的数字略大的数字
        swap(nums[i],nums[j]);
        //交换
        reverse(nums.begin()+i+1,nums.end());
        //直接倒序,觉得这个应该比sort快?
        return;
    }
};

使用库函数

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
      //  vector<int> origin = nums;
        
        if(next_permutation(nums.begin(),nums.end())){

        }else {
            sort(nums.begin(),nums.end());
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值