77. Combinations

来源:互联网 发布:淘宝 武士刀 编辑:程序博客网 时间:2024/06/14 13:33

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

典型的递归回溯过程:

class Solution {private:    // 存储结果    vector<vector<int>> res;    // 求解c(n,k),当前已经找到的组合存储在c中,需要从start开始搜索新的元素    void generateCombinations(int n, int k, int start, vector<int>& c){        // 递归终止        if (c.size() == k){            res.push_back(c);            return;        }        // 递归过程        for (int i = start; i <= n; i++){            c.push_back(i);            generateCombinations(n, k, i+1, c);            c.pop_back(); //回溯过程,为下一次递归推入做准备        }        return;    }public:    vector<vector<int>> combine(int n, int k) {        res.clear();        // 边界条件        if (n <= 0 || k <= 0 || k > n) return res;        vector<int> c;        generateCombinations(n, k, 1, c);        return res;    }};

上述过程可以对递归树进行剪枝以优化:

// 求解c(n,k),当前已经找到的组合存储在c中,需要从start开始搜索新的元素void generateCombinations(int n, int k, int start, vector<int>& c){    // 递归终止    if (c.size() == k){        res.push_back(c);        return;    }    // 递归过程 , 剪枝优化    for (int i = start; i <= n - (k - c.size()) + 1; i++){        c.push_back(i);        generateCombinations(n, k, i + 1, c);        c.pop_back(); //回溯过程,为下一次递归推入做准备    }    return;}

测试代码如下:

int main() {    Solution s;    // 测试77 号问题    vector<vector<int>> v = s.combine(5, 2);    cout << "[" << endl;    for (vector<vector<int>>::iterator iter = v.begin(); iter != v.end(); iter++){        vector<int> combination = *iter;        cout << "  [ ";        for (vector<int>::iterator it = combination.begin(); it != combination.end(); it++)        {            cout << *it << " ";        }        cout << "]" <<endl;    }    cout << "]" << endl;    system("pause");    return 0;}

运行结果:

[  [ 1 2 ]  [ 1 3 ]  [ 1 4 ]  [ 1 5 ]  [ 2 3 ]  [ 2 4 ]  [ 2 5 ]  [ 3 4 ]  [ 3 5 ]  [ 4 5 ]]请按任意键继续. . .