LeetCode(31): 下一个排列

Medium!

题目描述:

(请仔细读题)

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

解题思路:

这道题让我们求下一个排列顺序,有题目中给的例子可以看出来,如果给定数组是降序,则说明是全排列的最后一种情况,则下一个排列就是最初始情况。我们再来看下面一个例子,有如下的一个数组:

1  2  7  4  3  1

下一个排列为:

1  3  1  2  4  7

那么是如何得到的呢,我们通过观察原数组可以发现,如果从末尾往前看,数字逐渐变大,到了2时才减小的,然后我们再从后往前找第一个比2大的数字,是3,那么我们交换2和3,再把此时3后面的所有数字转置一下即可,步骤如下:

1  2  7  4  3  1

1  2  7  4  3  1

1  3  7  4  2  1

1  3  1  2  4  7

C++解法一:

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

下面这种写法更简洁一些,但是整体思路和上面的解法没有什么区别。

C++解法二:

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

猜你喜欢

转载自www.cnblogs.com/ariel-dreamland/p/9134262.html