【发布时间】:2015-12-02 09:18:57
【问题描述】:
我最近在练习算法题。我发现了两个非常相似的问题,并将它们放在一起用于学习目的。
问题 1:拥有来自 n 的所有 k 个组合 - 例如n=4 和 k=3 然后我们返回 {[1,2,3],[1,3,4],[2,3,4],[1,2,4]}
答案:
public static List<List<Integer>> combine(int n, int k) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(k > n || n <= 0) {
return res;
}
ArrayList<Integer> a = new ArrayList<Integer>();
helper(res, n, k, 1, a);
return res;
}
private static void helper(List<List<Integer>> res, int n, int k, int start, ArrayList<Integer> a) {
if(a.size() == k){
res.add(new ArrayList<Integer>(a));
return;
}
for(int i=start; i<=n; i++) {
a.add(i);
helper(res, n, k, i+1, a);
a.remove(a.size()-1);
}
}
问题 2:具有数组的所有排列:{1,2,3} -> {123},{132},{213},{231},{321},{312}。
答案:
public static List<List<Integer>> permute(int[] num) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
if (num == null || num.length == 0) {
return rst;
}
ArrayList<Integer> list = new ArrayList<Integer>();
helper(rst, list, num);
return rst;
}
public static void helper(List<List<Integer>> rst, ArrayList<Integer> list, int[] num){
if(list.size() == num.length) {
rst.add(new ArrayList<Integer>(list));
return;
}
for(int i = 0; i<num.length; i++) {
if(list.contains(num[i])){
continue;
}
list.add(num[i]);
helper(rst, list, num);
list.remove(list.size() - 1);
}
}
对于问题2,我们从索引0开始;对于问题1,为什么for循环索引需要从start开始,为什么我们需要传递一个start参数给helper方法?
【问题讨论】:
-
顺便说一下,permute(n) = combine(n, n),所以不需要两个单独的实现
-
不,它们是不同的。 Combine(3,3) 只会给出 (1,2,3) 的结果 ....
-
@NiklasB。是的,不是出生或受教育的英语使用者,我最初的想法是一样的,所以我查了一下,发现Combination vs. Permutation的这个很好的解释
-
@catlovespurple,标签dfs是什么意思?
-
@AntonDanilov 深度优先搜索...
标签: java algorithm recursion depth-first-search