Given a set of candidate numbers (
candidates
) (without duplicates) and a target number (target
), find all unique combinations incandidates
where the candidate numbers sums totarget
. javascriptThe same repeated number may be chosen from candidates unlimited number of times. 前端
Note:java
- All numbers (including target) will be positive integers.
- The solution set must not contain duplicate combinations.
大意:给定一组不含重复数字的数组和一个目标数字,在数组中找出全部数加起来等于给定的目标数字的组合。git
candidates = [2,3,6,7], target = 7
[ [7], [2,2,3] ]
因为咱们须要找到多个组合,简单的使用 for
循环确定是不行的,这时候咱们能够使用回溯算法来解决这个问题。github
用回溯算法解决问题的通常步骤:算法
根据题目的描述咱们知道它知足了咱们所说的步骤一,下面咱们来肯定搜索的思路👇数组
回溯通常须要遍历全部的状况来找出问题的解,在写代码以前咱们不妨先画出一个递归树,理清咱们写代码的思路👇微信
因为数组中的数字是能够被重复使用的,因此对于同一个数字也要向下递归。可是,对于 [2,2,3]
和 [2,3,2]
这样的结果 实际上是重复的,咱们须要剔除掉重复的项。
能够这样优化递归树👇函数
刚刷题目的时候看到这类多种解的问题常常会感到懵逼,其实这里一般的解法是传入一个临时数组,进入递归前 push
一个结果,结束以前能够用一个全局数组保存下来,结束以后在临时数组中 pop
掉它。优化
结束条件一般题目中就会给出,通常来讲找到给出的解或者递归层数达到上限就能够结束递归
function foo (nums, target) { let result = [] dfs(0, 0, []) return result function dfs (index, sum, tmp) { if (sum === target) { result.push(tmp.slice()) } if (sum > target) { return } for (let i = index; i < nums.length; i++) { tmp.push(nums[i]) dfs(i, sum + nums[i], tmp) tmp.pop() } } }
对于这类题目,使用回溯算法显然很方便。固然,除了递归以外也能用 栈
或者 队列
来解决。另外,对于前端同窗,遇到须要开辟临时数组的题目时,若是存在赋值操做,记得返回它的浅复制,如 result.push(tmp.slice())
,不然会对结果产生影响。
原题地址: Combination Sum
代码不定时更新,欢迎 star
个人 repo
扫描下方的二维码或搜索「tony老师的前端补习班」关注个人微信公众号,那么就能够第一时间收到个人最新文章。