好久没更新。
最近主要忙几件事情:
帮老师发论文,我觉得是无用功。
Citygo进入华创杯决赛,忙着决赛准备。感觉这个作品还是可以的,虽然从暑假到现在都没更新。
自己实现了刷票。我现在就很想为网络投票这件事情来发表一下自己的看法。先放一边,等有时间再说。
贪玩。
所以就荒废了这个leetcode。
今天完成的是上一次就看到的题目,组合问题。
组合问题就是给n个数,求出这n个数的k组合的所有集合。
这个问题如果用递归就挺简单的,如果用非递归就挺复杂的。
之前一直在考虑应该不能用递归,因为太容易溢出了。
但是非递归一直没有好好地思考一下解法,感觉挺难的。
今天沉下心来做,想起之前也有一道类似的题目,直接用递归也就ac了。
所以我就尝试着用递归来做,竟然一遍通过了,哈哈。
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],
]
递归解法如下:
我们新定义一个函数,combination2(int start,int end,int k)
这个函数跟原文中要求的函数 combination(int n.int k)的区别就是
combination(n,k)=combination(1,n,k)
之所以使用后者是为了方便递归。
递归的形式可以很好地总结出来,
cb2(start,end,k)=cb2(start+1,end,k-1).add(start) || cb2(start+2,end,k-1).add(start+1) || ... || cb2(end-k+2,end,k-1).add(end-k+1)
其中 ||表示结果集并,add(x)表示在结果集中的每个list中都加入元素x。
当k==1的时候可以直接给出答案。也就是递归结束。
所以,整到题目也就解决了。
上代码:
import java.util.ArrayList;
import java.util.List;
public class combinations {
public List<List<Integer>> combine2(int start, int end, int k) {
List<List<Integer>> result = new ArrayList<>();
if (k == 1) {
for (int i = start; i <= end; ++i) {
List<Integer> tmplist=new ArrayList<>();
tmplist.add(i);
result.add(tmplist);
}
return result;
}else {
for(int i=start;i<=end-k+1;++i){
List<List<Integer>> tmpresult=combine2(i+1,end, k-1);
for(List<Integer> tmpchild:tmpresult){
tmpchild.add(0,i);
result.add(tmpchild);
}
}
return result;
}
}
public List<List<Integer>> combine(int n, int k) {
return combine2(1, n, k);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}