描述:
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就 “回溯” 返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为 “回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。
1 出口。 一个递归算法一定要有出口,否则就是一个死循环了。出口语句一般都挺好写的,但 是出口语句该放在哪儿了,这个就是关键了,这儿容许我先卖个关子。
2 递归函数的参数。 一般情况下,递归函数是要带参数的,因为递归操作都是用来处理下一次的过程,如果没有参数的话,那么就很难从下一次的操作回溯到当前操作了。这么说,可能会有点迷糊,别急,后面我会举例子,这儿还是卖个关子。
3 递归函数的处理过程。 这个自不必多说,重中之重,需要好好理解其过程
上面3点就是我总结的关于回溯法的关键点了,我觉得只要真正的把这3步吃透,一般的回溯法题目是ok。
class Solution():
def Path(self,参数):
"函数布局,产生随机矩阵,"
# 调用同类下方法,返回所需值
self.Find_path(参数)
# 对所需值进行再处理
return 结果
def PD_K(self,参数):
"将复杂约束条件设定"
def Find_path(self,参数):
"对四个位置进行探索,并对所走路径填1"
对起始位置[0][0]设置为1
# 如果采用方法之间的调用,则需要将将约束条件融合
if j+1<n and self.PD_K(参数) and 标记位:
对走过位置标记
return self.Find_path(参数)
elif 四个位置讨论
else:
return 所需结果
注意跳出条件是有顺序的
- 首先是大范围(矩阵边界)
- 其次是中等范围(特殊条件)
- 最后是走过的痕迹标1(不能重复)
示例分析:
1 矩阵中的路径问题
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。
如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
例如 a b c e s f c s a d e e 矩阵中包含一条字符串”bcced”的路径,
但是矩阵中不包含”abcb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
解法:
首先,遍历这个矩阵,我们很容易就能找到与字符串str中第一个字符相同的矩阵元素ch。然后遍历ch的上下左右四个字符,如果有和字符串str中下一个字符相同的,就把那个字符当作下一个字符(下一次遍历的起点),如果没有,就需要回退到上一个字符,然后重新遍历。为了避免路径重叠,需要一个辅助矩阵来记录路径情况。
下面代码中,当矩阵坐标为(row,col)的格子和路径字符串中下标为pathLength的字符一样时,从4个相邻的格子(row,col-1)、(row-1,col)、(row,col+1)以及(row+1,col)中去定位路径字符串中下标为pathLength+1的字符。
如果4个相邻的格子都没有匹配字符串中下标为pathLength+1的字符,表明当前路径字符串中下标为pathLength的字符在矩阵中的定位不正确,我们需要回到前一个字符串(pathLength-1),然后重新定位。
一直重复这个过程,直到路径字符串上所有字符都在矩阵中找到格式的位置(此时str[pathLength] == ‘\0’)