Leetcode 学习计划之21天算法 (九)

 第9天 广度优先搜索 / 深度优先搜索 

542. 01矩阵

题目含义:距离1最近的0有多远

 1、DFS爆搜会超时。即只搜1附近的0,第一层上下左右没有,就搜下一层。注意这里需要记录层数,层数即为距离。

#seen不用数组,而用set存储也行。下面为超时代码:

#BFS爆搜
class Solution(object):
    def updateMatrix(self, mat):
        """
        :type mat: List[List[int]]
        :rtype: List[List[int]]
        """
        ans = mat
        l = len(mat)
        w = len(mat[0])
        for i in range(l):
            for j in range(w):
                if mat[i][j] == 1:
                    ans[i][j] = 0
                    queue = []
                    seen = set()
                    queue.append([i,j])
                    seen.add((i,j))
                    find = False                    
                    while not find:
                        length = len(queue)
                        for _ in range(length):
                            k, t = queue.pop(0)
                            for x,y in ([k-1,t],[k+1,t],[k,t-1],[k,t+1]):
                                if 0<=x<l and 0<=y<w and (x,y) not in seen:
                                    if mat[x][y] == 0:
                                        find = True
                                        ans[i][j] +=1
                                        break
                                    else:
                                        queue.append([x,y])
                                        seen.add((x,y))                            
                            if find:
                                break
                            length -= 1
                            if length == 0:
                                ans[i][j] +=1
        return ans

2、多源BFS。思想:找0附近的1。 0距0本身长度为0,0上下左右一层的1距离0的长度为1,在外层1距离1的距离为1,距离0的距离为2,依此类推。先把所有0入队,逐渐出队的过程中把0周围的1入队,直到队空,所有都遍历完毕。

多源BFS就不像单源BFS一样最初只入队一个结点,而是入对多个结点,作为初始节点。出队过程二者类似,注意seen数组别忘记。

class Solution:
    def updateMatrix(self, mat):
        seen = set()
        l =len(mat)
        w = len(mat[0])
        queue = []
        for i in range(l):
            for j in range(w):
                if mat[i][j] == 0:
                    queue.append((i,j))
                    seen.add((i,j))
        while queue:
            f,s = queue.pop(0)
            for x,y in ([f-1,s],[f+1,s],[f,s-1],[f,s+1]):
                if 0<=x<l and 0<=y<w and (x,y) not in seen:
                    mat[x][y] = mat[f][s] + 1
                    seen.add((x,y))  
                    queue.append((x,y))                      
        return mat

994. 腐烂的橘子 

思路:

多源BFS。队列+seen集合。先把坏橘子(值为2)都入队。然后判断其上下左右是否没被访问,是不是=1即为橘子,满足条件就入队。注意这里需要记录层数(即题目中的耗时),在每次pop前记录queue的len即可实现。当前len长都出队了,说明这一层遍历完了,level层数+1,此外还要判断这一层是不是判空了(即最后一次可能没有橘子可以腐蚀了),这是引入一个flag变量判断,这里用了stillLive。 

class Solution(object):
    def orangesRotting(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        l = len(grid)
        w = len(grid[0])
        queue = []
        seen = set()
        for i in range(l):
            for j in range(w):
                if grid[i][j] == 2:
                    queue.append((i,j))
                    seen.add((i,j))
        level = 0
        while queue:
            stillLive = False
            size = len(queue)
            for _ in range(size):
                f,s = queue.pop(0)
                for x,y in ([f-1,s],[f+1,s],[f,s-1],[f,s+1]):
                    if 0<=x<l and 0<=y<w and (x,y) not in seen and grid[x][y]==1:
                        grid[x][y] = 2
                        queue.append((x,y))
                        seen.add((x,y))
                        stillLive = True
            if stillLive:
                level+=1
        for t in range(l):                
            if 1 in grid[t]:
                return -1
        return level

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值