回溯算法
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
回溯算法的框架
result = []
function backtrack(路径, 选择列表){
if(满足结束条件)
{
result.add(路径)
return;
}
for(let i = 0 ; i < 选择列表的长度 ;i++)
{
做选择
backtrack(路径, 选择列表)
撤销选择
}
}
其核心就是 for 循环里面的递归,在递归调用之前「做选择」,在递归调用之后「撤销选择」,特别简单。
回溯算法能解决了什么问题
全排列、子集、 递增子序列、 N皇后
全排列
解题思路
解题思路:
用递归模拟全部的路,直到path 长度等于 nums 长度,这就到了死路,就可以结束递归,最后要记得递归之后回溯的操作
var str = 'abc', ret = [], strArr = str.split('')
// 这个方法可以理解为往下添加不重负的元素
function backtrake(path) {
if(path.length === strArr.length) { ret.push(path.join('')); return } // 递归的终止条件
for(let i = 0; i < strArr.length; i++) {
if(path.includes(strArr[i])) continue; // 排除重复项
path.push(strArr[i]) // 添加有用项
backtrake(path) // 递归
path.pop() // 回溯
}
}
backtrake([])
console.log(ret)
人生很漫长,或许我只是你人生中微不足道的一小段,只是你人生中的惊鸿一瞥。