Leetcode: Combinations

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],
]

感觉应该是用DFS,就是想不出来。只好自己瞎琢磨,结果一个复杂的东西,算是backtrack吧。

class Solution {
public:
    vector<vector<int> > combine(int n, int k) {
        vector<vector<int> > result;
        if (n < k) {
            return result;
        }
        
        vector<int> v;
        combineUtil(result, v, 1, n, k);
        
        return result;
    }
    
    void combineUtil(vector<vector<int> > &result, vector<int> &v, int start, int end, int k) {
        if (v.size() == k) {
            result.push_back(v);
            v.pop_back();
            combineUtil(result, v, start, end, k);
        }
        else {
            if (start <= end) {
                v.push_back(start);
                combineUtil(result, v, start + 1, end, k);
            }
            else {
                while (!v.empty()) {
                    int last = v.back();
                    v.pop_back();
                    if (end - last >= k - v.size()) {
                        combineUtil(result, v, last + 1, end, k);
                        break;
                    }
                }
            }
        }
    }
};
真正的DFS几行就可以搞定,不需要思考太多。

class Solution {
public:
    vector<vector<int> > combine(int n, int k) {
        vector<vector<int> > result;
        if (n < k) {
            return result;
        }
        
        vector<int> v;
        combineUtil(result, v, 1, n, 0, k);
        
        return result;
    }
    
    void combineUtil(vector<vector<int> > &result, vector<int> &v, int start, int end, int dep, int maxdep) {
        if (dep == maxdep) {
            result.push_back(v);
            return;
        }
        else {
            for (int i = start; i <= end; ++i) {
                v.push_back(i);
                combineUtil(result, v, i + 1, end, dep + 1, maxdep);
                v.pop_back();
            }
        }
    }
};
====================第二次==================
两种方式,需要清楚掌握什么时候需要循环,什么时候不需要循环,必须的,不能搞混了。
class Solution {
public:
    vector<vector<int> > combine(int n, int k) {
        vector<vector<int>> result;
        vector<int> comb;
        combine_util(result, comb, 1, n, k);
        
        return result;
    }
    
    void combine_util(vector<vector<int>> &result, vector<int> &comb, int start, int end, int remains) {
        if (remains == 0) {
            result.push_back(comb);
            return;
        }
        else if (end - start + 1 < remains) {
            return;
        }
        
        combine_util(result, comb, start+1, end, remains);
            
        comb.push_back(start);
        combine_util(result, comb, start+1, end, remains-1);
        comb.pop_back();
    }
};
上面因为有选择和不选择两个分支,所以不能有循环,要不然就重复了。

class Solution {
public:
    vector<vector<int> > combine(int n, int k) {
        vector<vector<int>> result;
        vector<int> comb;
        combine_util(result, comb, 1, n, k);
        
        return result;
    }
    
    void combine_util(vector<vector<int>> &result, vector<int> &comb, int start, int end, int remains) {
        if (remains == 0) {
            result.push_back(comb);
            return;
        }
        
        for (int i = start; i <= end - remains + 1; ++i) {
            comb.push_back(i);
            combine_util(result, comb, i+1, end, remains-1);
            comb.pop_back();
        }
    }
};
这个一直选择,所以需要循环。

你可能感兴趣的:(LeetCode,DFS)