Leetcode | 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, 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

分析了一下,得出有以下规律,accepted。大体思路和网上一样。红色部分是网上的解法。

1. 从右往左扫,找到第一个不符合num[i]>=num[i+1]的数;

2. 然后从[i+1...n-1]中找到比num[i]大的最小数num[j];这里我直接找大于num[i]的最小值了;其实因为[i+1..n-1]是递减的,可以从右往左扫,找到第一个数就退出就行了。

3. 交换num[j]和num[i];交换之后,仍然会保证[i+1...n-1]是递减的。

4. 对[i+1...n-1]进行排序;因为[i+1...n-1]是递减的,直接reverse就可以了,不需要排序。 

5. 如果找到的数i<0,也就是整个序列都是递减的,那么直接排序就行;同样可以用reverse

 1 class Solution {
 2 public:
 3     void nextPermutation(vector<int> &num) {
 4         int i;
 5         for (i = num.size() - 2; i >= 0; --i) {
 6             if (num[i] >= num[i + 1]) continue;
 7             int minIndex = i + 1;
 8             for (int j = i + 1; j < num.size(); ++j) {
 9                 if (num[j] > num[i] && num[j] < num[minIndex]) minIndex = j;
10             }
11             swap(num[i], num[minIndex]);
12             sort(num.begin() + i + 1, num.end());
13             break;
14         }
15         if (i < 0) sort(num.begin(), num.end());
16     }
17 };

不过因为可以不用写reverse的代码,直接用sort看起来简洁得多。重构了一下代码就是:

 1 class Solution {
 2 public:
 3     void nextPermutation(vector<int> &num) {
 4         int i, j;
 5         for (i = num.size() - 2; i >= 0 && num[i] >= num[i + 1]; --i); 
 6         if (i >= 0) {
 7             for (j = num.size() - 1; j > i && num[j] <= num[i]; --j); 
 8             swap(num[i], num[j]);
 9         } 
10         sort(num.begin() + i + 1, num.end());
11     }
12 };

 

转载于:https://www.cnblogs.com/linyx/p/3734451.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值