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老師的前端補習班」關注個人微信公衆號,那麼就能夠第一時間收到個人最新文章。