leetcode31:Next Permutation

来源:互联网 发布:网络运维工资是多少 编辑:程序博客网 时间:2024/06/05 06:03

题目:

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

The replacement must be in-place, do not allocate extra memory.

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

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

思路:

没碰到这个问题的朋友可能根本不晓得题目想说啥。

其实这是个典型的找下一个全排列问题。全排列大家都晓得,何为下一个全排列呢?

其实很简单,我们一般写全排列时,都有一定顺序,即下一个全排列与前一个有尽可能多的公共前缀。但是注意,如果一个序列是递减的,则不具有下一个全排列。

124653为例

最后一个数字为3,显然不具有下一个全排列

最后两个数字为53,也不具有下一个全排列

最后三个数字为653,也不具有下一个全排列

最后四个数字为4653,因为不是递减的,所有具有下一个全排列。

说到这里,相信大家对全排列有了一定了解。那么怎样确定下一个全排列呢?

首先明确4后面的几个数字中至少有一个大于4.

4肯定要和653这3个数字中大于4的数字中(6,5)的某一个进行交换。这里就是4要和6,5中的某一个交换,很明显要和5交换,如果找到这样的元素呢,因为我们知道4后面的元素是递减的,所以在653中从后面往前查找,找到第一个大于4的数字,这就是需要和4进行交换的数字。这里我们找到了5,交换之后得到的临时序列为5643.,交换后得到的643也是一个递减序列。


所以得到的4653的下一个临时序列为5643,但是既然前面数字变大了(4653--->5643),后面的自然要变为升序才行,变换5643得到5346.

所以124653的下一个序列为125643.

当然如果一直到最前面一个数字得到的序列都是递减序列,说明该序列没有下一个全排列,按照题目的要求,需要对序列进行升序排列。

时间复杂度:O(n)

class Solution {public:void nextPermutation(vector<int>& nums) {int size = nums.size(),index=size-1;if (size < 2) return;for (; index > 0; index--){if (nums[index] > nums[index - 1]) break;}if (index == 0)change(nums,0,size-1);else{int index1 = size - 1;while (nums[index1] <= nums[index - 1])index1--;swap(nums[index1], nums[index - 1]);change(nums, index, size - 1);}}private:void change(vector<int> &nums,int low,int high){if (low >= high) return;swap(nums[low], nums[high]);change(nums,low+1,high-1);}};


0 0
原创粉丝点击