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 }
permutations

相关文章: