leetcode 39. Combination Sum

Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.

For example, given candidate set 2,3,6,7 and target 7
A solution set is: 
[7] 
[2, 2, 3] 



class Solution {
	struct Info
	{
		vector<pair<int, int>>pre;//pair<int,int>里的first代表sinnums里的index,second代表个数  
		int remainsize;//剩余的数字个数  
		int remainvalue;//剩余的值  
	};
	vector<vector<int>>re;
	void choose_one(int&k, vector<Info>&candi, vector<int>candidates)
	{
		vector<Info>newcandi;
		if (k == 1)
		{
			for (int i = 0; i < candi.size(); i++)//考虑0  
				if (candi[i].remainvalue%candi[i].remainsize == 0)
				{
					int nxtnum = candi[i].remainvalue / candi[i].remainsize;
					if (nxtnum>candidates[candi[i].pre.back().first] &&
						find(candidates.begin(), candidates.end(), nxtnum) != candidates.end())
					{
						vector<int>aa;
						for (int j = 0; j < candi[i].pre.size(); j++)
							for (int h = 0; h < candi[i].pre[j].second; h++)
								aa.push_back(candidates[candi[i].pre[j].first]);
						for (int j = 0; j < candi[i].remainsize; j++)
							aa.push_back(nxtnum);
						re.push_back(aa);
					}
				}
			k--;
			return;
		}
		else
		{
			for (int i = 0; i < candi.size(); i++)
			{
				for (int j = 1; j <= candi[i].remainsize - k + 1; j++)
				{
					for (int h = candi[i].pre.back().first + 1; h < candidates.size() - k + 1; h++)
					{
						//粗略做判断,减小候选集大小  
						if (candi[i].remainvalue <= candidates[h] * j + candidates.back()* (candi[i].remainsize - j)
							&& candi[i].remainvalue >= candidates[h] * j + candidates[h + 1] * (candi[i].remainsize - j))
						{
							Info info;
							info.pre = candi[i].pre;
							info.pre.push_back(pair<int, int>(h, j));
							info.remainsize = candi[i].remainsize - j;
							info.remainvalue = candi[i].remainvalue - j*candidates[h];
							if (info.remainsize>0 && info.remainvalue >= candidates[h + 1] * info.remainsize)
								newcandi.push_back(info);
						}
					}
				}
			}
			k--;
			candi = newcandi;
			return;
		}
	}

public:
	vector<vector<int>> combinationSum(vector<int>& candidates, int target)
	{
		if (candidates.empty() || target <= 0)
			return re;
		sort(candidates.begin(), candidates.end());
		if (candidates.front() > target)
			return re;
		for (int i = 0; i < candidates.size(); i++)
			//答案里只有一种数字  
			if (target%candidates[i] == 0)
			{
				vector<int>aa(target / candidates[i], candidates[i]);
				re.push_back(aa);
			}
		for (int i = 0; i < candidates.size(); i++)
		{
			//答案里有k种数字,2<=k<=neednum
			int need = target / candidates[i];
			if (need >= 2)
			{
				for (int neednum = 2; neednum <= need; neednum++)
					for (int k = 2; k <= neednum; k++)
					{
						if (candidates.size() - i >= k)
						{
							for (int j = 1; j <= neednum - k + 1; j++)
							{
								Info inf;
								inf.pre.push_back(pair<int, int>(i, j));
								inf.remainsize = neednum - j;
								inf.remainvalue = target - j*candidates[i];
								vector<Info>candi;
								candi.push_back(inf);
								int kk = k - 1;
								while (kk > 0)
									choose_one(kk, candi, candidates);
							}
						}
					}
			}
		}
		return re;
	}
};

accepted


你可能感兴趣的:(LeetCode)