组合总和--力扣

Posted 穿迷彩服的鲨鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合总和--力扣相关的知识,希望对你有一定的参考价值。


前言

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。

说明:所有数字(包括 target)都是正整数。解集不能包含重复的组合。


一、示例

示例 1:

输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:

输入:candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

二、代码解析

1.搜索回溯

思路与算法

对于这类寻找所有可行解的题,我们都可以尝试用「搜索回溯」的方法来解决。

回到本题,我们定义递归函数 dfs(target, combine, idx) 表示当前在 candidates 数组的第 idx 位,还剩 target 要组合,已经组合的列表为 combine。

递归的终止条件为 target <= 0 或者 candidates 数组被全部用完。

那么在当前的函数中,每次我们可以选择跳过不用第 idx 个数,即执行 dfs(target, combine, idx + 1)。
也可以选择使用第 idx 个数,即执行 dfs(target - candidates[idx], combine, idx),注意到每个数字可以被无限制重复选取,因此搜索的下标仍为 idx。
更形象化地说,如果我们将整个搜索过程用一个树来表达,即如下图呈现,每次的搜索都会延伸出两个分叉,直到递归的终止条件,这样我们就能不重复且不遗漏
地找到所有可行解:

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/combination-sum/solution/zu-he-zong-he-by-leetcode-solution/
来源:力扣(LeetCode)

在这里插入图片描述

代码如下(示例):

/*搜索回溯*/
/*递归的终止条件为 target <= 0 或者 candidates 数组被全部用完。*/
void Recursion(vector<int>& candidates, int target, vector<vector<int>>& result, vector<int>& combine, int index)
{
	if (index==candidates.size())
	{
		return;
	}
	if (target==0)
	{
		result.emplace_back(combine);
		return;
	}
	Recursion(candidates, target, result, combine, index + 1);
	if (target-candidates[index]>=0)
	{
		combine.emplace_back(candidates[index]);
		Recursion(candidates, target - candidates[index], result, combine, index);
		combine.pop_back();
	}
}

vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
{
	vector<int> combine;
	vector<vector<int>> result;
	Recursion(candidates, target, result, combine, 0);
	return result;
}

2.测试代码

代码如下(示例):

#include<iostream>
#include<vector>
using namespace std;

/*搜索回溯*/
/*递归的终止条件为 target <= 0 或者 candidates 数组被全部用完。*/
void Recursion(vector<int>& candidates, int target, vector<vector<int>>& result, vector<int>& combine, int index)
{
	if (index==candidates.size())
	{
		return;
	}
	if (target==0)
	{
		result.emplace_back(combine);
		return;
	}
	Recursion(candidates, target, result, combine, index + 1);
	if (target-candidates[index]>=0)
	{
		combine.emplace_back(candidates[index]);
		Recursion(candidates, target - candidates[index], result, combine, index);
		combine.pop_back();
	}
}

vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
{
	vector<int> combine;
	vector<vector<int>> result;
	Recursion(candidates, target, result, combine, 0);
	return result;
}

int main()
{
	vector<int> candidates = { 2, 3, 6, 7 };
	int target = 7;
	vector<vector<int>> nums = combinationSum(candidates,target);
	for (int i = 0; i < nums.size(); i++)
	{
		for (int j = 0; j < nums[i].size(); j++)
		{
			cout << "[" << nums[i][j] << "]";
		}
		cout << endl;
	}
	return 0;
}

3.测试结果

在这里插入图片描述

总结

在这里插入图片描述

以上是关于组合总和--力扣的主要内容,如果未能解决你的问题,请参考以下文章

组合总和 I(力扣第39题)

力扣-39(40)-组合总和I(II)

力扣39.组合总数

力扣39.组合总数

40. 组合总和 II

40. 组合总和 II