Difficulty Medium算法
tags two-pointers
permutation
數組
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.code
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).ip
The replacement must be in-place, do not allocate extra memory.leetcode
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.get
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
it
思路io
這是一個不難從觀察中獲得方法的算法, 並且即便在數組中有相同的元素的狀況下也能經過細微的改動在~N的時間複雜度下實現此算法。class
以 [1, 4, 3, 2] 爲例, 其下一個排列爲 [2, 1, 3, 4]方法
經過觀察能夠發現,將上一個排列轉換到下一個排列的過程當中, 咱們的思考方式是這樣的:
排列尾部的[4,3,2]已經達到了2,3,4這三個元素造成的排列中最大的一個, 因此咱們必須考慮換掉數組頭上的1來實現下一個排列。
所以,天然咱們須要從2,3,4中挑選一個最接近1的:2 來放在排列頭部。 而後,由於2是新的隊首, 後面的排列取順序遞增排列便可。
原來的尾部排列已經逆向有序, 咱們將要替換的兩個最接近的元素交換後, 並不影響其有序性。因此,將尾部數組再逆序一下就是順序數組了。
也即咱們所求的排列。
solution 1
class Solution { public: void nextPermutation(vector<int>& nums) { int n = nums.size(); int p = n-2; while (p>=0 && nums[p]>=nums[p+1]){ p--; } if (p>=0) { int min_diff = INT_MAX, ptr = p+1, pos; while (ptr<n) { if (nums[ptr]>nums[p] && nums[ptr]-nums[p]<=min_diff) { min_diff = nums[ptr]-nums[p]; pos = ptr; } ptr++; } swap(nums[p], nums[pos]); } reverse(nums.begin()+p+1, nums.end()); } };