>"是谁在新年旅行时还在写题解我不说"
戳我看原题
题目大意
算了直接上原文:
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
思路
经常写题的佬们一定都看出来了,这是一道简单的回溯(dfs)题,同样的,也可看作一道dp题,采用完全背包问题的板子就能解决。
我的写法是dfs。
什么是dfs?
别问我,我不知道
深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接
dfs应该如何去写?
这边是一个我经常用的模板(仅供参考)
点击查看代码
vector<int> path;vector<vector<int>> result;void backTracking(......) {if (......) {......return;}for (int i = 0; i < size; ++i) {path.emplace_back(......);backTracking(......);path.pop_back();}}
有关dfs的剪枝
我们不难看出看不出也算了如果不剪枝得出的答案会出现重复现象,因此在进行回溯时本层起始元素的下标必须大于或等于上一层元素的下标。
代码实现请看下文。
你以为本文就只有这一点吗?
不,接下来是lambda!
lambda表达式
为何我会在本文提到lambda?因为这是力扣中的回溯(递归思想)题,Lambda表达式可以使代码更加简洁和易读,并且看起来也更高级。
简单理解lambda
放个链接:
https://blog.csdn.net/m0_60134435/article/details/136151698
lambda中dfs的写法:
auto dfs = [&](auto&& dfs, int i, int j) -> int {}
注意,在递归使用dfs时应写为dfs(dfs,i,j);
代码实现
点击查看代码
class Solution {
public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {int n=candidates.size();vector<vector<int>>x;vector<int>y;auto dfs = [&] (auto&& dfs,int num,int next) {if(num>=target){if(num==target){x.push_back(y);}return ;}for(int i=next;i<n;i++){y.push_back(candidates[i]);dfs(dfs,num+candidates[i],i);y.pop_back();}};dfs(dfs,0,0);return x;}
};
总结
这道题是个极其基础的板子题,这篇题解主要是想让大家了解一下lambda的递归用法(虽然说感觉没人会看)。
Xhita我目前正坐在宾馆的温暖被窝中,你问我去了哪里?
避暑圣地神农架!
所以说谁会在大冬天去神农架啊,还是大年初一,路上吃的都没有