Leetcode 31 Next Permutation (C++实现)

题目:
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, do not allocate 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

这个题目最无语的地方在于一般人看不懂题目要求说的是什么。尤其是lexicographically这个关键词让人一脸懵逼。题目的意思就是,还是这几个数字,找出比当前排列大的排列中最小的那一个。

奥斯卡的叫法经过在草稿纸上演算了几种情况之后,得到下面可以想到的不需要分类讨论的通法(唯一一个需要注意的就是是否没有比当前大的排列了——序列中的数字是降序,这时应该返回最小的排列——所有数字的升序序列。)

算法:
1. 从所给序列nums的尾部开始向前搜索,搜索过的序列记为S,直到发现下降的相邻数字,或者搜索到序列首。
2. if 没有搜索到序列首:
a = S前面的数字
b = S中比a大的最小的数字
交换a和b
3. 对S进行升序(非降序)排序

#include <iostream>
#include <vector>
using namespace std;

// We can define another function swap() to make the codes clearer. reverse(), too.

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int temp = -1;
        int i;
        int len = nums.size();
        vector<int> seq;
        for(i = len - 1; i >= 0; i--) {
            if (nums[i] >= temp) {              
                temp = nums[i];
                seq.push_back(temp);   // the numbers in seq vector is in forward order.
            }
            else
                break;
        }

        if (i != -1) {
            int t = nums[i];
            for (int j = 0; j < seq.size(); j++) {
                if (seq[j] > t) {
                    nums[i] = nums[len-1-j];
                    nums[len-1-j] = t;
                    break;
                }
            }
        }

        for (int j = 0; j < (len-1-i)/2; j++) {
            int t = nums[i+1+j];
            nums[i+1+j] = nums[len-1-j];
            nums[len-1-j] = t;
        }
    }
};



int main() {
    Solution s;
    vector<int> nums;
    nums.push_back(1);
    nums.push_back(2);
    nums.push_back(3);
    // 测试123的所有排序是否按序输出
    for(int i = 0; i < 6; i++) {
        s.nextPermutation(nums);
        for (int j = 0; j < nums.size(); j++) {
            cout << nums[j] << " ";
        }
        cout << endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值