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