您的位置:首页 > 其它

(Leetcode)31. Next Permutation

2016-06-22 21:21 441 查看

Problem

31. Next Permutation:

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.递归思路

一个给定数组

int nums[] = {1,3,4,2}


从后往前,先比较最末尾两个数,
nums[head]
nums[tail]
。其中
head=length-2,tail=length-1


如果
nums[head]<nums[tail]
,那么直接把这两个数互换,next premutation找到,算法complete。e.g.: 1,2,3,4->1,2,4,3

如果不是,即
nums[head]>=nums[tail]
,那么把
head=head-1
,向前扩充一个数。

如果
nums[head]>=nums[head+1]
,继续把
head=head-1
,再向前扩充一个数,重新回第4步。

如果不是,即
nums[head]>=nums[head+1]


注意:这个时候nums[head+1] ~nums[tail]一定是降序排列的。

(a) 找到比在这个范围中比nums[head]大的最小的数,index标记为target。(因为后面的元素一定是是降序排列,所以直接从末尾开始找,第一个就是target)

(b)把nums[head]和nums[target]互换。

注意:这个时候nums[head+1]~nums[tail]任然是降序排列的。

例如:{1,3,4,2}中,nums[head]=3,找到target=2,即’4’的index.互换后数组变成{1,4,3,2},{3,2}任然是降序,但这个不是最终结果。

(c) 然后对nums[head+1]~nums[tail]进行原地逆序。

例如:{1,4,3,2}中{3,2}逆序成{2,3},数组变成{1,4,2,3},找到了{1,3,4,2}的next permutation,算法complete。

如果全部扩充完毕,还是没找到,说明这个数组是个降序数组{4,3,2,1},他的next Permutation是最小的(升序,{1,2,3,4})。直接把这个数组原地逆序就可以了。

重要函数的解释:

nextPermutation(int[] nums): 返回nums的下一个全排列

ReverseArray(int[] nums, int head, int tail):将nums[]的head~tail的元素原地逆序。

Java

package _31NextPermutation;

public class Solution {
public void nextPermutation(int[] nums) {
if(nums.length<=1){
return;
}
else{
if(recursiveNextPermutation(nums, nums.length-2, nums.length-1)){
return;
}
else{
ReverseArray(nums,0,nums.length-1);
}
}
}

boolean recursiveNextPermutation(int[] nums, int head, int tail ){
if( head>=tail || head<0 ){
return false;
}
else if( (head+1)==tail ){
if(nums[head]<nums[tail]){
int temp = nums[head];
nums[head] = nums[tail];
nums[tail] = temp;
return true;
}
else{
return recursiveNextPermutation(nums,head-1,tail);
}
}
else{
if(nums[head]<nums[head+1]){
//find target
int target = tail;
while(nums[head]>=nums[target]){
target--;
}
//swap head and target
int temp = nums[head];
nums[head] = nums[target];
nums[target] = temp;

ReverseArray(nums, head+1, tail);
return true;
}
else{
return recursiveNextPermutation(nums,head-1,tail);
}
}
}

/**
* reverse the array
* @param nums
* @param head
* @param tail
*/
void ReverseArray(int[] nums, int head, int tail){
int i = head;
int j = tail;
while(i<j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++;
j--;
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int nums[]={1,5,1};
int k=0;
while(k<20){
new Solution().nextPermutation(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i]+" ");
}
System.out.println();
k++;
}
}

}


2.非递归思路

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