Leetcode46 Permutations
来源:互联网 发布:知乎jenny wang 事件 编辑:程序博客网 时间:2024/05/23 01:58
Permutations
Given a collection of numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].
Solution1
- 典型的回溯问题,回溯问题一般说来用递归方法求解会比较简单
public class Solution { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> result = new ArrayList<List<Integer>>(); HashSet<Integer> set = new HashSet<Integer>(); permute(nums,set,new ArrayList<Integer>(),result); return result; } public void permute(int[] nums,HashSet<Integer> set,List<Integer> item,List<List<Integer>> result){ if(item.size()==nums.length){ result.add(item); return; } for(int i=0;i<nums.length;i++){ if(set.contains(nums[i])) continue; List<Integer> temp = new ArrayList<Integer>(item); temp.add(nums[i]); HashSet<Integer> newSet = new HashSet<Integer>(set); newSet.add(nums[i]); permute(nums,newSet,temp,result); } }}
Solution2
- 用迭代的方法来实现上述回溯过程如下:
public class Solution { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> result = new ArrayList<List<Integer>>(); if(nums.length==0) return result; Stack<Integer> stack = new Stack<Integer>(); HashSet<Integer> set = new HashSet<Integer>(); List<Integer> item = new ArrayList<Integer>(); while(true){ for(int i=0;i<nums.length;i++){//往下递归的过程 if(set.contains(i)) continue; stack.push(i); set.add(i); item.add(nums[i]); break; } if(item.size()==nums.length){ result.add(new ArrayList<Integer>(item)); item.remove(item.size()-1); set.remove(stack.pop()); int j; for(j = nums.length;j>=nums.length;){//实现回溯过程 if(stack.empty()) return result; j = stack.pop(); set.remove(j); item.remove(item.size()-1); for(j++;j<nums.length&&set.contains(j);j++); } stack.push(j); set.add(j); item.add(nums[j]); } } }}
- 从上可以看出,一般说来,用迭代的方法来实现递归,都要借用到栈来保存当前的数组下标,在合适的时候回溯时,要在这个下标的地方往下递归,所以这里使用到栈来保存下标,但是可以看到迭代方法比较复杂。
Solution3
- 另一种类型的递归,更加trick一些
public class Solution { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> result = new ArrayList<List<Integer>>(); permute3(nums,0,result); return result; } public void permute3(int[] nums,int start,List<List<Integer>> result){ if(start==nums.length){ List<Integer> item = new ArrayList<Integer>(); for(int num:nums) item.add(num); result.add(item); return; } for(int i=start;i<nums.length;i++){ int temp = nums[start]; nums[start] = nums[i]; nums[i] = temp; permute3(nums,start+1,result); nums[i] = nums[start]; nums[start] = temp; } }}
Solution4
- 这里实际可以用动态规划的方法来求解。基本思路如下:当数组为[1]时,则答案为[1];当数组为[1,2]时,则答案为[1,2]和[2,1];当数组为[1,2,3]时,则答案可以在[1,2]和[2,1]的基础上构成。即往这两个数组中的不同位置插入3即可。如此得到下面的解法
import java.util.List;import java.util.ArrayList;public class Solution { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> result = new ArrayList<List<Integer>>(); if(nums.length==0) return result; List<Integer> temp = new ArrayList<Integer>(); temp.add(nums[0]); result.add(temp); for(int i=1;i<nums.length;i++){ int size = result.size(); for(int j=0;j<size;j++){ temp = result.get(j); for(int k=0;k<=temp.size();k++){//这里便是各个位置插入的过程 ArrayList<Integer> temp1 = new ArrayList<Integer>(temp); temp1.add(k,nums[i]); result.add(temp1); } } while(size-->0) result.remove(0); } return result; }}
Solution5
- 这里借鉴 Leetcode31 Next Permutation的思路来求解本题。
public class Solution { public List<List<Integer>> permuteUnique(int[] nums) { List<List<Integer>> result = new ArrayList<List<Integer>>(); Arrays.sort(nums); while(true){ List<Integer> item = new ArrayList<Integer>(); for(int num:nums) item.add(num); result.add(item); int i,j; for(i=nums.length-1;i>0;i--) if(nums[i-1]<nums[i]) break; if(i<=0) break; for(j=nums.length-1;j>0;j--) if(nums[j]>nums[i-1]) break; int temp = nums[j]; nums[j] = nums[i-1]; nums[i-1] = temp; for(j = nums.length-1;i<j;i++,j--){ temp = nums[j]; nums[j] = nums[i]; nums[i] = temp; } } return result; }}
- 思路清晰易懂,并且还复用性还非常高。不管是有重复数字还是没有重复数字都可以用这种方法求解。所以比回溯法更值得推荐。
0 0
- LeetCode46:Permutations
- Leetcode46 Permutations
- leetcode46. Permutations
- LeetCode46 Permutations
- LeetCode46 Permutations
- leetcode46. Permutations
- LeetCode46——Permutations
- Leetcode46——Permutations
- leetcode46/47-Permutations I/II(全排列问题)
- Leetcode46: Power of Two
- leetcode46简单动态规划
- Permutations
- Permutations
- Permutations
- Permutations
- Permutations
- Permutations
- Permutations
- hdu 1171 Big Event in HDU(母函数)
- n阶乘求最后非0数字及最后面连续0的个数
- hdu5057 分块法
- tarjan算法之 强连通分量
- 学习方法的思考
- Leetcode46 Permutations
- 另外十条千金不卖的人生感悟
- hdu5120 两圆环相交 数学题
- STM32F407vet6使用FSMC驱动LCD屏
- 2033 人见人爱A+B
- 10004--SpringMVC @PathVariable 映射 URL 绑定的占位符 /{xxx}
- [读书笔记—学习方法]《如何高效学习》- 斯科特·杨
- HDU 1507 Uncle Tom's Inherited Land* 二分图最大匹配(基础题)
- go语言的指针