《剑指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))

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容

  • 01 “我的爱情,生于校园,死于背叛”,这是小桔失恋后更新的朋友圈。 这个北方姑娘,不远万里来到南方求学。只记得学...
    奶猫妹阅读 411评论 1 5
  • 姓名:王成 公司:浙江中兴精密集团 六项精进277期学员(组长) 六项精进426期志工(感谢一组) 宁波盛和塾成立...
    王成_19ae阅读 84评论 0 0
  • 对不起,亲爱的,我好累 有些话一但是我说出口了就代表我真的忍的很辛苦了 对不起,亲爱的,我在哭 对我坦白一件事到底...
    落尘f雪阅读 531评论 0 2
  • 在丧到极点时,总忍不住想要叨咕发泄,可回头看看,愈发觉得那些沮丧的表情言辞甚至标点符号都是极其幼稚且荒唐可笑的,丝...
    苏子苏子阅读 134评论 0 0