您的位置:首页 > 其它

LeetCode 31. Next Permutation

2017-04-12 16:34 417 查看
题目:

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

思路:

字典排序(lexicographical order)是一种对于随机变量形成序列的排序方法。

其方法是,按照字母顺序,或者数字小大顺序,由小到大的形成序列。

比如说有一个随机变量X包含{1 2 3}三个数值。其字典排序就是{1 2 3} {1 3 2} {2 1 3} {2 3 1} {3 1 2} {3 2 1}本体题意是给定一个数组及其一个排列,找出其下一个字典排序序列;

例如:{6,8,7,4,3,2}

step1:从后向前查找第一个非递增的数value1,记录其位置p;ex:6,p=0;

step2:分两种情况:

1)若数组从后往前依次递增,则说明这是最后一个数列,下一个数列就是的一个数列;

ex;{8,7,6,4,3,2},则下一个为其逆序数组,即{2,3,4,6,7,8}.

2)若value1存在,其位置为p,再从后往前查找数组,找到第一个比value1大的数字value2,交换value1和value2;

ex:存在第一个非递增的数6,其位置为0;从后往前遍历,第一个比6大的数字是7,交换6和7:{7,8,6,4,3,2}

step3:数组中位置p之后的部分逆序;

ex:从位置p+1(a[1])开始,将数组剩余部分逆序;{7,2,3,4,6,8}

最坏情况需要遍历数组三次,所以时间复杂度是O(3*n)=O(n),空间复杂度是O(1)

代码:

class Solution {
public:
void nextPermutation(vector<int>& nums) {
int len = nums.size();//取nums的长度
if (len == 1){//如果为1,直接中止返回
return;
}
if (len == 2){//如果为2,交换后中止返回
swap(nums[0], nums[1]);
return;
}
int index = -1;//索引初始值
int i = len - 1;//i从len-1开始(末尾)遍历
int j = i;//保存i的位置
while (i > 0){//当i大于0时
if (nums[i]>nums[i - 1]){//如果nums[i]>nums[i-1],取i-1的索引
index = i - 1;
break;
}
--i;
}

if (index == -1){//如果index为-1,证明所有数都是从大到小,直接反转输出最小的情况
reverse(nums.begin(), nums.end());
}
else{
for (j; j>index; j--){//j从len-1位置找,在大于index时
if (nums[j]>nums[index]){//如果找到nums[j]>nums[index]
swap(nums[index], nums[j]);//交换
break;
}
}
reverse(nums.begin() + index + 1, nums.end());//前将index后面的数反转
}
}
};


**程序输出:**9ms

注:C++标准库中还有这个函数,直接一句就行。

next_permutation( nums.begin(), nums.end() );
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: