您的位置:首页 > 其它

【leetcode】31. Next Permutation

2016-04-20 13:26 435 查看
题目:

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


翻译:

翻译 实现“下一个排列”函数,将排列中的数字重新排列成字典序中的下一个更大的排列。 如果这样的重新排列是不可能的,它必须重新排列为可能的最低顺序(即升序排序)。 重排必须在原地,不分配额外的内存。 以下是一些示例,左侧是输入,右侧是输出: 1,2,3 → 1,3,2...

思路:

本题考察字典序排列,具体来说就是把一个序列看成一个数字,把数字的每一位进行全排列之后的所有可能,再按照大小排序,最后的结果就是字典序排列的结果。举个例子:

123,132,213,231,312,321

就是一个字典序排列的结果。本题给出一个中间的结果,让你输出下一个中间结果。如果输入的中间结果是最后一个结果,那么返回最初的值(即最小的值)。

这一题其实还难想出解法的。我们考虑从nums的尾部开始遍历,直到找到两个相邻的位置上的数满足nums[i]<nums[j],其中j=i+1。找到之后再从nums的尾部重新遍历一遍,找到第一个满足nums[i]<nums[k]的位置k,此处k>i即可,k与j有可能重合。交换nums[i]和nums[k],之后再将从j到数组尾部的元素全部倒序输出即可。

代码:
代码中写了一个reverse函数来配合上述算法
class Solution {
public:
void nextPermutation(vector<int>& nums) {
if (nums.size()<=1)
{
return;
}
int i,j,k,temp;
bool last_turn=true;
for (j=nums.size()-1;j>=1;j--)
{
i=j-1;
if(nums[j]>nums[i])
{
last_turn=false;
break;
}
}
if (last_turn)
{
reverse(nums,0,nums.size()-1);
return;
}
else
{
for (k=nums.size()-1;k>i;k--)
{
if (nums[k]>nums[i])
{
temp=nums[k];
nums[k]=nums[i];
nums[i]=temp;
reverse(nums,j,nums.size()-1);
break;
}
}
}
return;
}
void reverse(vector<int>& nums,int x,int y)
{
if (x>=y)
return;
int temp;
for (;x<y;x++,y--)
{
temp=nums[x];
nums[x]=nums[y];
nums[y]=temp;
}
return;
}
};
结果:

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