深度优先搜索|79, 695, 212

文章介绍了如何使用深度优先搜索(DFS)解决两个问题:单词搜索和计算岛屿的最大面积。在单词搜索中,DFS配合回溯法找到单词在二维矩阵中的路径;而在计算岛屿面积时,DFS直接遍历并标记已访问的单元格来确定最大连续1区域的大小。
摘要由CSDN通过智能技术生成

深度优先搜索|79. 单词搜索, 695. 岛屿的最大面积, 212. 单词搜索 II

单词搜索

用的是深度优先搜索,这种判断类型的回溯我就一直不知道要怎么回退,然后勉强写了一个。
这里还有一个注意事项就是,走到最后一个元素的时候,我设置的direction list里头就只有用过的几个元素,再加上我写的if used这个时候他就走不下去了,也不会到下一层的index+1了,这个时候又可以观察到,如果走到最后有一个元素了和word也对得上其实并不需要再去看有没有direction了,直接去index+1不用管i,j是谁就能直接True,所以这个地方可以加一个判断就是如果走到这里已经在word最后一个字母后面了,直接True。
然后写到这里就会发现,如果直接出去了,那么

if index == len(word):
	return True 

这句好像根本不需要,后来发现确实不需要。

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        def direction(i,j,m,n):
            l = [[i-1,j],[i+1,j],[i,j-1],[i,j+1]]
            if i == 0:
                l.remove([i-1,j])
            if j == 0:
                l.remove([i,j-1])
            if i == m-1:
                l.remove([i+1,j])
            if j == n-1:
                l.remove([i,j+1])
            return l 
        
        def backtracking(index,i,j):
            #if index == len(word):
                #return True 
            
            l = direction(i,j,m,n)
            if board[i][j] != word[index]: return False

            used[i][j] = True
            for k1,k2 in l:
                if index == len(word) - 1:
                    return True 
                if used[k1][k2]: 
                    continue
                if backtracking(index+1,k1,k2):
                    return True
            if l == [] and index == len(word)-1:
                return True

            used[i][j] = False
            return False
        
        m = len(board)
        n = len(board[0])
        used = [[False]*n for _ in range(m)]

        for i in range(m):
            for j in range(n):
                if backtracking(0,i,j):
                    return True 
        return False

岛屿的最大面积

这个题没上面的难,因为他知道是1都是连着的,所以不用回退。

class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        def direction(i,j,m,n):
            l = [[i-1,j],[i+1,j],[i,j-1],[i,j+1]]
            if i == 0:
                l.remove([i-1,j])
            if j == 0:
                l.remove([i,j-1])
            if i == m-1:
                l.remove([i+1,j])
            if j == n-1:
                l.remove([i,j+1])
            return l 
        
        m = len(grid)
        n = len(grid[0])
        used = [[False]*n for _ in range(m)]
        def backtracking(i,j):
            nonlocal res
            if grid[i][j] == 0: return 0
            l = direction(i,j,m,n)
            
            res += 1
            used[i][j] = True
            for k1,k2 in l:
                if used[k1][k2]:
                    continue
                backtracking(k1,k2)
            return 

        island = 0
        for i in range(m):
            for j in range(n):
                res = 0
                backtracking(i,j)
                island = max(island,res)
        return island

单词搜索II

在上一题的基础上加了一层循环,然后剪枝了一下,大多数还是能运行,就是太长了就超时了
42 / 65,这里有个要点是,每次单词的used list都要重新设,不然路都堵死了。

class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        def direction(i,j,m,n):
            l = [[i-1,j],[i+1,j],[i,j-1],[i,j+1]]
            if i == 0:
                l.remove([i-1,j])
            if j == 0:
                l.remove([i,j-1])
            if i == m-1:
                l.remove([i+1,j])
            if j == n-1:
                l.remove([i,j+1])
            return l 
        
        def backtracking(index,word,i,j):
            
            l = direction(i,j,m,n)
            if board[i][j] != word[index]: return False

            used[i][j] = True
            for k1,k2 in l:
                if index == len(word) - 1:
                    return True 
                if used[k1][k2]: 
                    continue
                if backtracking(index+1,word,k1,k2):
                    return True
            if l == [] and index == len(word)-1:
                return True

            used[i][j] = False
            return False
        
        m = len(board)
        n = len(board[0])
        res = []

        for k in words:
            used = [[False]*n for _ in range(m)]
            for i in range(m):
                if k in res:
                    break
                for j in range(n):
                    #print(i,j,k,res)
                    if k in res:
                        break
                    if backtracking(0,k,i,j):
                        res.append(k)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值