《剑指offer》12.矩阵中的路径

题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。
路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。
如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。例如 :
a b c e
c f c s 
a d e e 
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,
因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

这道题思路其实是很简单的,就是回溯法。
先找到第一个匹配的字符,然后从它的四周找下一个字符,如果找到了,接着往下找。
如果没找到,那么返回上一个字符从另一个方向找。
比如找"bfce",先找到b,在第一行的第二个,再找下一个字符'f'。
然后b的左方'a'不是,下方'f'是。那么再找下一个'c'。
'f'的左方'c'是,再找下一个'e'。
'c'的左边没有,下边是'a',不对。右边'f'是访问过的。注意,题目中要求一条路径不能有循环,所以先判断的是'f'有没有访问过。上方'a'也不对。
所以这个节点是错误的。
返回'f'节点,刚才只找了'f'的左边,现在找下面'd',不对。右边'c',匹配。
再从'c'往下找'e',左边访问过,下面'e'匹配。目标字符串找完了。返回结果存在该路径。
思路是很简单的,但是如何实现代码还是有一点难度的,怎样找到一条路径,怎么确定没有重复访问,还是需要思考的。
python代码如下:

def has_path(matrix, path):
    rows = len(matrix)
    cols = len(matrix[0])
    if not matrix or rows < 0 or cols < 0 or path is None:  # 参数合法性检测
        return False
    mark_matrix = [0] * (rows * cols)  # 表示matrix中的字符是已被访问,因为题目中路径必须是单向的
    path_index = 0  # 表示当前正在查找path中的第几位

    for row in range(rows):
        for col in range(cols):
            if has_path_core(matrix, rows, cols, row, col, path, path_index, mark_matrix):
                return True
    return False


def has_path_core(matrix, rows, cols, row, col, path, path_index, mark_matrix):
    if path_index == len(path):  # 表示path中所有字符都已匹配,则返回True
        return True
    hp = False
    # 1.参数合法性检查 2.matrix[row][col]和path[path_index]匹配 3.当前位置没有被访问过
    if 0 <= row < rows and 0 <= col < cols and matrix[row][col] == path[path_index] and \
            not mark_matrix[row * cols + col]:
        path_index += 1  # 匹配path中的下一个字符
        mark_matrix[row * cols + col] = True  # 当前位置已被访问过,不可再次访问
        # 递归查找四周的字符
        hp = has_path_core(matrix, rows, cols, row + 1, col, path, path_index, mark_matrix) or \
             has_path_core(matrix, rows, cols, row - 1, col, path, path_index, mark_matrix) or \
             has_path_core(matrix, rows, cols, row, col + 1, path, path_index, mark_matrix) or \
             has_path_core(matrix, rows, cols, row, col - 1, path, path_index, mark_matrix)
        # 如果四周都没有和path[path_index]相匹配的,则当前路径错误,退回到path中的上一个字符,并将该位置置为可读
        if not hp:
            path_index -= 1
            mark_matrix[row * cols + col] = False
    return hp


if __name__ == '__main__':
    path = 'bfce'
    matrix = [['a', 'b', 't', 'g'], ['c', 'f', 'c', 's'], ['j', 'd', 'e', 'h']]
    print(has_path(matrix, path))

代码中已经加了比较详细的注释,有些地方还是需要仔细思考。用个实际的例子,跟着代码的流程走一走。

你可能感兴趣的:(《剑指offer》12.矩阵中的路径)