码迷,mamicode.com
首页 > 其他好文 > 详细

Combinations 解答

时间:2015-10-18 06:36:31      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

Question

Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.

For example,
If n = 4 and k = 2, a solution is:

[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

Solution

Draw out solution tree. Given [4, 2]

            []

      /    /    \    \

     1    2     3    4

    / | \  / \     |

   2   3   4  3    4             4

According to this tree, we can write out solution.

 1 public class Solution {
 2     public List<List<Integer>> combine(int n, int k) {
 3         if (k > n)
 4             k = n;
 5         List<List<Integer>> result = new ArrayList<List<Integer>>();
 6         dfs(n, k, 1, new ArrayList<Integer>(), result);
 7         return result;
 8     }
 9     
10     private void dfs(int n, int k, int start, List<Integer> list, List<List<Integer>> result) {
11         if (list.size() == k) {
12             result.add(new ArrayList<Integer>(list));
13             return;
14         }
15         
16         for (int i = start; i <= n; i++) {
17             list.add(i);
18             dfs(n, k, i + 1, list, result);
19             list.remove(list.size() - 1);
20         }
21     }
22 }

Conclusion -- start pointer or visited[]

总结一下Backtracking这一类常见问题。

Backtracking一般都是应对穷举来找出所有答案的问题。对于这类问题,我们常常可以画出解空间树。然后遍历解空间树就可以得到答案。

遍历可以用 BFS 也可以DFS。一般来说,用迭代实现的DFS,不用自己维护栈所以是比较方便的做法。如果用BFS,则需要纪录一系列状态值。

在迭代的时候,我们要注意迭代结束之后要回到未迭代时的状态。

1. 如果有list操作,要把list的最后一个element移出

2. 如果有visited[],重新设置该element的状态为未访问过。

对比这些题目 Permutation, PhoneNumber,我们发现有的时候用到了start指针来代替visited[]数组表明该结点都无访问过。

那什么时候用start指针,什么时候用visited[]呢?

??????????????????我是树的分割线??????????????????

关键还在于画出的解空间树。

比如Combination这道题

            []

      /    /    \    \

     1    2     3    4

    / | \  / \     |

   2   3   4  3    4             4

我们发现当第一个元素选为2,它再往下走的时候,就不用再从1开始遍历,否则时间空间浪费太对,会time limits exceed。

再看Permutation的解空间树

            []

      /    /    \    \

    1    2     3    4

  / | \     /  | \   /  | \     /  | \ 

 2   3   4    1   3    4   1   2    4  1   2   3

...............

我们发现对于每一层的每一个结点,接下来它要遍历的个数都是3。因此这里我们需要visited[]来判断在一条route上的点是否遍历过。

 

后记

其实对于树的遍历,我们也不需要visited[],因为树没有环。而对于图的遍历,我们需要visited[]。 

Combinations 解答

标签:

原文地址:http://www.cnblogs.com/ireneyanglan/p/4888799.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!