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).spa

The replacement must be in-place and use only constant extra memory.code

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.blog

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1索引

 

题目大意:按照字典序生成排列,给定一个排列,生成下一个排列。ip

首先,咱们观察到,对于任何按降序排列的给定序列,都不可能出现下一个更大的排列。例如,下面的数组不可能有下一个排列:get

[9,5,4,3,1]it

咱们须要从右边找到知足a[i]>a[i -1]的两个连续数字a[i]和a[i-1]的前一对。如今,a[i-1]右边的任何从新排列都不能产生更大的排列,由于该子数组由降序数字组成。所以,咱们须要把数字从新排列到a[i-1]包括它自身的右边。io

那么,什么样的从新排列会产生下一个更大的数呢?咱们想要建立一个比当前更大的置换。所以,咱们须要将数字a[i-1]替换为数字a[j]。a[j]为i - 1后大于a[i - 1]的最小数。class

咱们交换数字a[i -1]和a[j]。但目前的排列仍然不是咱们要找的排列。咱们须要一种最小的排列,这种排列只能由a[i-1]右边的数组成。所以,咱们须要将这些数字按升序排列,以获得它们最小的排列。

 

可是,请记住,当咱们从右边扫描这些数字时,咱们只是不断地减少索引,直到找到a[i]和a[i−1]对,其中a[i]>a[i−1]。所以,a[i-1]右边的全部数都已按降序排列。此外,交换a[i-1]和a[j]并无改变顺序。所以,咱们只须要将a[i-1]后面的数字倒转,就能够获得下一个最小的词典排列。

 1 class Solution {
 2 public:
 3     void nextPermutation(vector<int>& nums) {
 4         int i = nums.size() - 2;
 5         while (i >= 0 && nums[i] >= nums[i + 1]) {
 6             --i;
 7         }
 8         if (i >= 0) {
 9             int j = nums.size() - 1;
10             while (nums[j] <= nums[i]) {
11                 --j;
12             }
13             swap(nums[i], nums[j]);
14         }
15         reverse(nums, i + 1, nums.size() - 1);
16     }
17 private:
18     void reverse(vector<int> &nums, int start, int end) {
19         while (start < end) {
20             swap(nums[start++], nums[end--]);
21         }
22     }
23 };
相关文章
相关标签/搜索