LeetCode77 Combinations 组合 C++

问题描述:

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

Example:

Input: n = 4, k = 2
Output:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

题源:here;完整实现:here

思路:

两种方案:1 递归法;2 构造法。虽然两种方法从时间上分析都是一样的,但是因为递归法会有一些无效的判断和递归调用代价,总的效率是比较低的,但是代码实现简单直观。

1 递归法

	void addOne(vector<int> in, vector<int> out, vector<vector<int>> &result, int k){
		if (out.size() == k){
			result.push_back(out);
			return;
		}
		for (int i = 0; i < in.size(); i++){
			vector<int> tempIn = in;
			vector<int> tempOut = out;
			tempIn.erase(tempIn.begin(), tempIn.begin()+i+1);
			tempOut.push_back(in[i]);
			addOne(tempIn, tempOut, result, k);
		}
	}
	vector<vector<int>> combine(int n, int k) {
		vector<int> in; vector<vector<int>> result;
		for (int i = 0; i < n; i++) in.push_back(i + 1);
		addOne(in, {}, result, k);
		return result;
	}

2 构造法

我们构造一个数组ones来表示一种组合模式,ones中的1表示从1-n中提取,0表示不提取。当ones中出现10模式时就将其置换为01,请将该模式前所有的1挪到最左边,当所有的1都在最右边时终止程序。

    	vector<vector<int>> combine2(int n, int k){
		vector<int> ones(n), lib(n); vector<vector<int>> result;
		for (int i = 0; i < n; i++){
			ones[i] = (i < k) ? 1 : 0; lib[i] = i+1;
		}
		while (1){
			vector<int> solution; bool flag = false;
			for (int i = 0; i < n; i++){
				if (ones[i]) solution.push_back(lib[i]);
			}
			result.push_back(solution);
			int count = 0;
			for (int i = 0; i < n - 1; i++){
				if (ones[i] == 1 && ones[i + 1] == 0){
					flag = true;
					ones[i] = 0; ones[i + 1] = 1;
					for (int j = 0; j < i; j++){
						ones[j] = count-->0 ? 1 : 0;
					}
					break;
				}
				else if (ones[i]) count++;
			}
			if (!flag) break;
		}

		return result;
	}

贴出运行结果纪念一下:

扫描二维码关注公众号,回复: 2163867 查看本文章


猜你喜欢

转载自blog.csdn.net/m0_37518259/article/details/80963387
今日推荐