(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 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- leetcode----Longest Substring Without Repeating Characters
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解
- LeetCode[Day 2] Median of Two Sorted Arrays 题解
- LeetCode[Day 3] Longest Substring Without... 题解
- LeetCode [Day 4] Add Two Numbers 题解