Combinations

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

典型的DFS,循环递归,典型的递归回溯法,多做形成这个递归回溯头脑,就好办了。

1 递归一次,填入一个数字

2 填入的数字,不能是小于当前数字的值,防止重复

3 回溯:记得pop_back()最后加上的一个数字,回溯到上一层。

4 结束条件:填写够了k个数字的时候,当前填写完毕,回溯

c++代码如下:

class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<vector<int> > res;  
        vector<int> cur;  
        rec(res, cur, n, k, 1);  
        return res;  
    }  
private:  
    void rec(vector<vector<int> > &res, vector<int> &cur,const int n, const int k,  int m) {  
        if(cur.size() == k) {  
            res.push_back( cur );  
             
            return;  
        }      
          
        for(int i=m; i<=n; i++) {  
                cur.push_back( i );  
                rec(res, cur, n, k, i+1);  //循环递归的过程比较复杂,需要认真理解
                cur.pop_back();  
        }  
    }
};



java代码如下:
 
<pre name="code" class="java">public class Solution {
    private List<List<Integer>> res = new ArrayList<List<Integer>>();//只能这样向上转型
    //private List<List<Integer>> res = new ArrayList<ArrayList<Integer>>();//不能这样转型,这样是不对的
    
    public List<List<Integer>> combine(int n, int k) {
        if(n<=0 || n<k) return null;
        List<Integer>item = new ArrayList<Integer>(); 
        helper(n,k,1,item);
        return res;
    }
    
    public void helper(int n,int k,int start,List<Integer> item) {
        if(item.size()==k) {
            res.add(new ArrayList<Integer>(item));
           // res.add(item);//注意不能这样,因为添加进去的是item的引用,而后面item里的内容还在不断变化,导致res里的内容仍然是在变化的
            return;
        }
        for(int i=start;i<=n;i++) {
            item.add(i);
            helper(n,k,i+1,item);   //循环递归,很巧妙,认真理解
            item.remove(item.size()-1);
        }
    }
}


 

具体例如:先item[1],然后item[1,2],添加到res,然后item移除末尾变成[1],再添加,变成[1,3],类似[1,4],[1],然后5不能加入,[1]->[],再从[2]开始循环下去

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


[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值