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], ]
中文翻譯就是:給定數字n與k,產生k種排列
這題就是要產生所有的組合,然後我們這邊是使用DFS,逐一拜訪每個可能產生的元素,過程類似像下面這樣:
第一次dfs 第二次dfs
=====================================
m = 1 temp = [1], m = 2 temp = [1,2]
m = 3 temp = [1,2]
m = 4 temp = [1,4]
m = 2 temp = [2], m = 3 temp = [2,3]
m = 4 temp = [2,4]
m = 3 temp = [3], m = 4 temp = [3,4]
於是我們可以寫出代碼:
package LeetCode.Medium;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author ZiHan
* 從n取k,不重複
*
* ex: n = 4, k = 2
* [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
* 有3個變量 n, k, m
* dfs1 dfs2
* ========================================================
* m = 1 temp = [1], m = 2 temp = [1,2]
* m = 3 temp = [1,2]
* m = 4 temp = [1,4]
* m = 2 temp = [2], m = 3 temp = [2,3]
* m = 4 temp = [2,4]
* m = 3 temp = [3], m = 4 temp = [3,4]
*/
public class Combinations {
public List<List<Integer>> combine(int n, int k) {
//結果
List<List<Integer>> result = new ArrayList<>();
//暫存結果
List<Integer> temp = new ArrayList<>();
//進行深度搜索,從1開始(m=1)
dfs(result, temp, n, k, 1);
return result;
}
/*
temp 暫存結果
n 共多少個
k n取k個
m 目前從第m個數字開始
*/
void dfs(List<List<Integer>> result, List<Integer> temp, int n, int k, int m) {
//結果可以了ex:[1,2],加入結果
if(k == 0) {
result.add(new ArrayList<Integer>(temp));
return;
}
//開始於m,類似於排列,逐個數字拜訪
for(int i = m; i <= n; i ++) {
temp.add(i);
dfs(result, temp, n, k - 1, i + 1);
temp.remove(temp.size() - 1);
}
}
}