[关闭]
@w1024020103 2017-07-12 02:39 字数 1224 阅读 625

Subsets

LeetCode LintCode


在此输入正文

image_1bkp64s7o1u37kdm94b1j1khmjm.png-35.2kB

详细解说

这道题题目要求所有可能的子集。老师说过,碰到让你找所有方案的题,一定要用DFS.

image_1bkpc22lk1ha6djn9r8rdbclv13.png-67.8kB

回溯法的图示:
回溯法可用图示和函数运行的堆栈图来理解,强烈建议使用图形和递归的思想分析,以数组[1, 2, 3]进行分析。下图所示为list及resul t动态变化的过程,箭头向下表示list.add及result.add操作,箭头向下表示list.remove操作。
http://7xiys0.com1.z0.glb.clouddn.com/gitbook143117722134.jpgimage_1bkpc3vp81edd18171t241vtk187p1t.png-1639.8kB

  1. // 递归:实现方式,一种实现DFS算法的一种方式
  2. class Solution {
  3. /**
  4. * @param S: A set of numbers.
  5. * @return: A list of lists. All valid subsets.
  6. */
  7. public ArrayList<ArrayList<Integer>> subsets(int[] nums) {
  8. ArrayList<ArrayList<Integer>> results = new ArrayList<>();
  9. if (nums == null) {
  10. return results;
  11. }
  12. if (nums.length == 0) {
  13. results.add(new ArrayList<Integer>());
  14. return results;
  15. }
  16. Arrays.sort(nums);
  17. helper(new ArrayList<Integer>(), nums, 0, results);
  18. return results;
  19. }
  20. // 递归三要素
  21. // 1. 递归的定义:在 Nums 中找到所有以 subset 开头的的集合,并放到 results
  22. private void helper(ArrayList<Integer> subset,
  23. int[] nums,
  24. int startIndex,
  25. ArrayList<ArrayList<Integer>> results) {
  26. // 2. 递归的拆解
  27. // deep copy
  28. // results.add(subset);
  29. results.add(new ArrayList<Integer>(subset));
  30. for (int i = startIndex; i < nums.length; i++) {
  31. // [1] -> [1,2]
  32. subset.add(nums[i]);
  33. // 寻找所有以 [1,2] 开头的集合,并扔到 results
  34. helper(subset, nums, i + 1, results);
  35. // [1,2] -> [1] 回溯
  36. subset.remove(subset.size() - 1);
  37. }
  38. // 3. 递归的出口
  39. // return;
  40. }
  41. }

以这个问题为例子,要好好训练自己找到递归三要素的能力:递归的定义,递归的拆解,递归的出口。比如本体中递归的定义,也就是helper method要做的事情,便是找到以传入参数subset开头的所有subsets,并且加入到results里面。

self explanation

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注