今天在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