今天在LeetCode看到一篇很是有價值的討論,列舉了一系列列數組的回溯算法
的通用模式,本身動手一個個完成後,感受對理解回溯算法的原理有很大幫助。算法
原地址數組
其實回溯就是按順序的一種窮舉,可是它會設定中止條件
和達成條件
app
一旦符合中止條件
,直接總體跳過,包括它後面的子集所有跳過code
一旦符合達成條件
,即是所須要的數據,添加到結果集合裏leetcode
一個簡單的例子:get
列舉數組arr的全部的長度相同的組合,字符不重複 例如:[1,2,3] 輸出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
代碼(js):it
function subSet(nums){ let result=[],temp=[] backtrack(result,temp,nums) return result function backtrack(result,temp,nums){ // 達成條件 if(temp.length===nums.length)result.push(temp.slice()) for(let i=0;i<nums.length;i++){ // 中止條件 if(temp.includes(nums[i]))continue temp.push(nums[i]) backtrack(result,temp,nums) temp.pop() } } }
它的運行軌跡:io
1 1 1 × 1 2 1 2 1 × 1 2 2 × 1 2 3 √ 1 3 1 3 1 × 1 3 2 √ 1 3 3 × 2 2 1 2 1 1 × 2 1 2 × 2 1 3 √ 2 2 × 2 3 2 3 1 √ 2 3 2 × 2 3 3 × 3 3 1 3 1 1 × 3 1 2 √ 3 1 3 × 3 2 3 2 1 √ 3 2 2 × 3 2 3 × 3 3 ×
一旦父級達到中止條件
,例如2 2
,像後面的子集2 2 1
,2 2 2
都不會進行function
當經過的中止條件
而且符合達成條件
的,就是結果。class