***leetcode刷题_(arr,dfs)_code79(单词寻找)

code79:Word Search

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

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

Given word = “ABCCED”, return true.
Given word = “SEE”, return true.
Given word = “ABCB”, return false.

解答:
类似的题目可以想到用回溯法解答,当出现想要的点时,进入下一层,如果周围出现接下来的点,继续。否则当前路径终止。

最开始的想法:
1 def1 寻找方向,当到达一个点时,可以有四条路径,这个时候进行判断然后返回可以进入下一步的数组
2 def2 寻找路径,进入当前点,调用方向方法def1 然后决定下一步 当出现len(word)==0时,得到一个True。
3 使用的全局变量,每次进行操作需要判断一次全局变量是否为True。True时则跳出,否则继续。(为了防止多余的操作)
4 因为每次操作数组,要排除已经操作的值,所以在def2中 将当前arr的当前值变为’#’,传入
5 因为这个方法调用时 所有的arr都会产生改变,设置一个deepcopy来每次还原数组。

代码:

import time
def singleton(func):
    def count(*args):
        a = time.time()
        res = func(*args)
        b = time.time()
        print(b-a)
        return res

    return  count



import copy

class Solution:
    @singleton
    def exist(self, board, word: str) -> bool:
        if len(word) == 0:
            return False

        global judge
        judge = False
        for i in range(len(board)):
            index = [j for j, x in enumerate(board[i]) if x == word[0]]
            #print(index)
            if index:
                for k in range(len(index)):
                    if not judge:
                        #print(i,k)
                        start = [i, index[k]]
                        #print(board)
                        new = copy.deepcopy(board)
                        #print(board,'?')
                        self.findpath(new, word[1:], start)
        return judge



    def findpath(self, board, word, start):
        print(board,word,start)
        global judge
        #print(board)
        #print(board)
        if len(word) == 0:

            judge = True
            return
        else:
            tar = word[0]
            x, y = start[0], start[1]
            #temp = board[x][y]
            board[x][y] = '#'
            #print(board)
            new_start = self.test_dir(board, x, y, tar)
            #print(new_start)
            #print(new_start,'#',tar)
            for i in range(len(new_start)):
                if not judge:
                    new = copy.deepcopy(board)
                    self.findpath(new, word[1:], new_start[i])
                    #board[x][y]=temp
                    #print(board)

    def test_dir(self,board, x, y, tar):
        arr = []
        if x - 1 >= 0:
            if board[x - 1][y] == tar:
                arr.append([x - 1, y])
        if y - 1 >= 0:
            if board[x][y - 1] == tar:
                arr.append([x, y - 1])
        if x + 1 <= len(board) - 1:
            if board[x + 1][y] == tar:
                arr.append([x + 1, y])
        if y + 1 <= len(board[0]) - 1:
            if board[x][y + 1] == tar:
                arr.append([x, y + 1])

        return arr

用了一个singleton来计时。

最后一个例子时TLE了。。。。理论上是没错的,但是操作比较繁琐。

参考答案:
同样使用了dfs,从第一个就开始进行判断
1 不在需要单独地寻找起点,而是直接遍历,判断是否为需要点。
2 同样进行了’#'取代当前字符的操作,但是最后在return之前,将其取代回来。这样对于同一水平上的调用不会出现数组不对的情况
3 len为0返回True,超出判定范围以及不等于返回False
4 正常情况下,返回四个方向上的 or集合!!!!
这个很关键,如果一旦一个or中为true 则会立即返回 不进行后面or 的操作

代码:

class Solution3:
    def exist(self, board, word: str) -> bool:
        if not board:
            return False
        for i in range(len(board)):
            for j in range(len(board[0])):
                if self.dfs(board, word, i, j):
                    return True
        return False

    def dfs(self, board, word, i, j):
        if len(word) == 0:
            return True
        if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or word[0] != board[i][j]:
            return False
        x = board[i][j]
        board[i][j] = '#'
        print(board,word[1:],i,j)
        res = self.dfs(board, word[1:], i - 1, j) or self.dfs(board, word[1:], i + 1, j) or self.dfs(board, word[1:], i,
                                                                                                     j - 1) or self.dfs(
            board, word[1:], i, j + 1)

        board[i][j]=x
        return res

tips:
1 dfs时,多考虑能否从第一步就出发
2 dfs的返回点(尽头点的处理)。本题中一旦同水平出现True,后面不再进行操作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值