Combinations

来源:互联网 发布:淘宝买家退货卖家拒收 编辑:程序博客网 时间:2024/06/08 13:56

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
原创粉丝点击