组合
题目描述:
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
class Solution {
private boolean[] used;
private int[] combination;
private List<List<Integer>> result;
private List<Integer> temp;
private int k;
private int n;
public List<List<Integer>> combine(int n, int k) {
// 初始化
this.k = k;
this.n = n;
this.combination = new int[n];
for(int i = 0 ; i<n ; i++) combination[i]=i+1;
this.used = new boolean[n];
this.result = new ArrayList<List<Integer>>();
this.temp = new ArrayList<Integer>();
DFS(0,0);
return result;
}
/**
* 第一个参数为当前的已经组合的元素个数
* 第二个参数为防止路径重叠
**/
private void DFS(int count,int begin){
if(count == this.k){
ArrayList<Integer> temp = new ArrayList<Integer>(); // 局部变量
for(int i=0 ; i<k ; i++) temp.add(this.temp.get(i));
this.result.add(temp);
return;
}
for(int i = begin ; i<this.n ; i++){
if(!used[i]){
used[i] = true;
this.temp.add(this.combination[i]);
DFS(count+1,i+1);
used[i] = false;
this.temp.remove(this.temp.size()-1);
}
}
}
}
继续优化后…
class Solution {
private List<List<Integer>> result;
private List<Integer> temp;
private int k;
private int n;
public List<List<Integer>> combine(int n, int k) {
// 初始化
this.k = k;
this.n = n;
this.result = new ArrayList<List<Integer>>();
this.temp = new ArrayList<Integer>();
DFS(1);
return result;
}
/**
* 第一个参数为当前的已经组合的元素个数
**/
private void DFS(int num){
if(this.temp.size() == this.k){
this.result.add(new ArrayList<Integer>(this.temp));
return;
}
if(num > this.n) return;
// 考虑当前的数字
this.temp.add(num);
DFS(num+1); // 对下一个数字位置开始收集
// 不考虑当前的数字
this.temp.remove(this.temp.size() - 1);
DFS(num+1); // 对下下一数字位置开始收集
}
}
典型的深度优先搜索算法,详细细节请看代码。优化之前需要利用两个额外的数组,优化之后不需要额外的数组空间。