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 };