【leetcode】Combinations (middle)

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

]

 

思路:有点像0-1背包问题, 对于从1-n的每一个数字都可以选择放入答案 和不放入答案。 当长度达到k时就是一个符合条件的解。

递归的代码,AC了。只要注意状态的还原就好。

#include <iostream>

#include <vector>

#include <algorithm>

#include <queue>

#include <stack>

using namespace std;



class Solution {

public:

    vector<vector<int> > combine(int n, int k) {

        vector<vector<int>> ans;

        combinepart(ans, 1, k, n);

        return ans;

    }



    void combinepart(vector<vector<int>> &ans, int num, int k, int n)

    {

        static int i = 0;

        static vector<int> partans;

        if(num - 1 > n || partans.size() + (n - num + 2) < k) return; //数字超过了n 或者即使后面数字全部压入长度也不够的时候 直接返回 避免不必要的计算

        if(i == k)

        {

            ans.push_back(partans);

            return;

        }



        partans.push_back(num); //放入num

        i++;

        combinepart(ans, num + 1, k, n);



        partans.pop_back();

        i--;

        combinepart(ans, num + 1, k, n);//不放入num

    }

};



int main()

{

    Solution s;

    vector<vector<int>> ans = s.combine(3,3);



    return 0;

}

 

网上有非递归的代码,可是我好困,懒得看... 速度都差不多的,因为我的递归截枝了,没有多余的操作。

class Solution {

public:

    vector<vector<int> > combine(int n, int k) {

    vector<vector<int> >ret;

    if(k>n||k<=0)return ret;



    for(int i=1;i<=n-k+1;i++){

        ret.push_back(vector<int>(1,i));

    }



    for(int i=2;i<=k;i++){

        int num=ret.size();

        for(int j=0;j<num;j++){

            int last=ret[j].back();

            vector<int> pretmp=ret[j];

            ret[j].push_back(last+1);

            for(int p=last+2;p+k-i<=n;p++){

                vector<int> tmp=pretmp;

                tmp.push_back(p);

                ret.push_back(tmp);

            }

        }

    }



    return ret;

}

};

 

你可能感兴趣的:(LeetCode)