79. 单词搜索

题目

给定一个二维网格和一个单词,找出该单词是否存在于网格中。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:

board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]

给定 word = “ABCCED”, 返回 true
给定 word = “SEE”, 返回 true
给定 word = “ABCB”, 返回 false

自练代码(一旦错了,无法回溯。。。)

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        hang = len(board)
        lie = len(board[0])

        index = 0
        for i in range(hang):
            for j in range(lie):
                if board[i][j] == word[index]:
                    path = [(i,j)]
                    ii, jj = i, j
                    now = index
                    ok = 1
                    if ok and now == len(word)-1:
                        return(True)
                    while(ok and now < len(word)):
                        now += 1
                        if ii+1<hang and board[ii+1][jj] == word[now] and (ii+1,jj) not in path:
                            ii = ii + 1
                            path.append((ii, jj))
                        elif ii-1>-1 and board[ii-1][jj] == word[now] and (ii-1,jj) not in path:
                            ii = ii - 1
                            path.append((ii, jj))
                        elif jj+1<lie and board[ii][jj+1] == word[now] and (ii,jj+1) not in path:
                            jj = jj + 1
                            path.append((ii, jj))
                        elif jj-1>-1 and board[ii][jj-1] == word[now] and (ii,jj-1) not in path:
                            jj = jj - 1
                            path.append((ii, jj))
                        else:
                            now -= 1
                            ok = 0
                            break
                        if ok and now == len(word)-1:
                            return(True)
                            exit()

                else:
                    continue
        return(False)

正解

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        # 为了稍后去遍历
        hang = len(board) # 字母板的行数
        lie = len(board[0]) # 字母板的列数

        def dfs(i, j, k, visited):
            if k == len(word): # 等于单词的长度则返回真,表示任务完成
                return True

            for x, y in [(-1, 0), (1, 0), (0, 1), (0, -1)]: # 只能向四周探寻
                tmp_i = x + i
                tmp_j = y + j
                if 0 <= tmp_i < hang and 0 <= tmp_j < lie and (tmp_i, tmp_j) not in visited \
                        and board[tmp_i][tmp_j] == word[k]: 
                # 满足三个条件:坐标不能出界,不能重复探寻点,是否和单词当前位置k的字母相等?
                    visited.add((tmp_i, tmp_j)) # 是的话,探寻!!!
                    if dfs(tmp_i, tmp_j, k+1, visited): # 是的话,继续做同样的探寻!
                        return True
                    visited.remove((tmp_i, tmp_j)) # 这次探寻没找到,需要删掉这个点继续探寻for循环中的其他点
            return  False # for循环中的所有点探寻完了,没有返回真,那么就是没找到了。。。。

        # 将每个字母板都作为开始字母
        for i in range(hang):
            for j in range(lie):
                if board[i][j] == word[0] and dfs(i, j, 1, {(i, j)}): 
                # 因为回溯的时候不能出界,所以要(i,j),因为到达长度要停止所以要传k,最后是已经遍历过字母的集合
                    return(True)
                    exit()
        return(False)

结果

结果

总结

DFS+回溯

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值