1.permutations
Given a list of numbers, return all possible permutations.
For nums = [1,2,3], the permutations are:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
显然需要需要用递归来找所有的全排列。关于这个递归,是返回找到的值加入到上层还是在把参数传到递归层,在递归层进行更新处理。对于分治策略,二叉树的问题,很明显左右子树能得到一个小问题的答案,大问题的答案是该小问题的答案的一个组合,那么用递归返回一个结果,在上层进行结合处理比较方便。对于这个题目,每次递归要做的事情是往下找permutations的下一个数字,在递归层处理结果更加自然。
注意深刻理解这个递归要干的事情,每一层分别是做什么的。
for (int i = 0; i < nums.length; i++) {
。。。
list.add(nums[i]);
helper(nums, result, list);
list.remove(list.size() - 1);
。。。
}
这个for循环其实是在便利nums数组,找到第一个合适的permutation的首字母,这也就是为什么找到第一个首字母的时候,我们要把它更新的结果里面。这时候需要找第二个字母,那么我们跳到第二层递归里面去找第二个,这也就是为什么,这个时候需要使用递归。当以当前首字母开头的permutations找到并且加入到全局结果里以后,我们需要找下一个合适的开头字母,所以要把当前的开头字母给清空,这也就是为什么需要做remove操作。
1 class Solution { 2 /** 3 * @param nums: A list of integers. 4 * @return: A list of permutations. 5 */ 6 public List<List<Integer>> permute(int[] nums) { 7 List<List<Integer>> result = new ArrayList<List<Integer>>(); 8 if (nums == null) { 9 return result; 10 } 11 List<Integer> list = new ArrayList<Integer>(); 12 helper(nums,result,list); 13 return result; 14 } 15 private void helper (int[] nums, List<List<Integer>> result, List<Integer> list) { 16 if (list.size() == nums.length) { 17 result.add(new ArrayList<Integer>(list)); 18 } 19 for (int i = 0; i < nums.length; i++) { 20 if (list.contains(nums[i])){ 21 continue; 22 } 23 list.add(nums[i]); 24 helper(nums, result, list); 25 list.remove(list.size() - 1); 26 } 27 } 28 }