(待更..)【Leetcode 广搜、动态规划】01 矩阵(542)

题目

给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。

示例 1:
输入:

0 0 0
0 1 0
0 0 0

输出:

0 0 0
0 1 0
0 0 0

示例 2:
输入:

0 0 0
0 1 0
1 1 1

输出:

0 0 0
0 1 0
1 2 1

注意:
给定矩阵的元素个数不超过 10000。
给定矩阵中至少有一个元素是 0。
矩阵中的元素只在四个方向上相邻: 上、下、左、右。

解答

也是一道搜索题。要找出每个非零数字和最近0的距离,用广度优先搜索很合适,以某个非零数字为起点,检查走一步的范围中是否包含0;若不包含,再检查走两步能到达哪些点,是否包含0;以此类推,直到碰到数字0,返回走过的步数。
1,广度优先搜索bfs,用队列实现。Time: O(mn),Space: O(mn)
2,写完这题又想了想,用深搜dfs也可以,每次从起点dfs找到0,会有多组解,取最小值,深搜过程中book先标记再取消。
3,动态规划,看题解有这个办法,待更..

广度优先搜索代码:

class Queue:  # 队列数据结构
    def __init__(self):
        self.x = 0
        self.y = 0
        self.distance = 0


class Solution:
    def __init__(self):
        self.book = []
        self.next = [
            [0, 1],
            [1, 0],
            [0, -1],
            [-1, 0]
        ]
        self.m = 0
        self.n = 0
        self.ans = []
        self.temp = []

    def updateMatrix(self, matrix):
        if not matrix:
            return []
        self.m, self.n = len(matrix), len(matrix[0])
        self.ans = [
            [0 for _ in range(self.n)] for _ in range(self.m)
        ]
        self.que = [Queue() for _ in range(self.m*self.n+1)]
        self.book = [
            [0 for _ in range(self.n)] for _ in range(self.m)
        ]

        for i in range(self.m):
            for j in range(self.n):
                self.temp = []  # 记录本次bfs标记的点,方便book清空复位;book很大的时候,每次都初始化会超时的。。。
                if matrix[i][j] == 0:
                    self.ans[i][j] = 0
                else:
                    head = tail = 1
                    self.que[tail].x = i
                    self.que[tail].y = j
                    self.que[tail].distance = 0
                    tail += 1
                    self.book[i][j] = 1
                    self.temp.append([i, j])

                    self.ans[i][j] = self.bfs(head, tail, matrix)
                for x in self.temp:  # book清空复位
                    self.book[x[0]][x[1]] = 0
        return self.ans

    def bfs(self, head, tail, matrix):
        while head < tail:
            for i in range(4):
                tx = self.que[head].x + self.next[i][0]
                ty = self.que[head].y + self.next[i][1]
                if tx >= 0 and ty >= 0 and tx < self.m and ty < self.n and self.book[tx][ty] == 0:
                    self.que[tail].x = tx
                    self.que[tail].y = ty
                    self.que[tail].distance = self.que[head].distance + 1
                    tail += 1
                    self.book[tx][ty] = 1
                    self.temp.append([tx, ty])  # 记录本次bfs标记的点
                    if matrix[tx][ty] == 0:
                        return self.que[tail - 1].distance
            head += 1


s = Solution()
ans = s.updateMatrix([[0, 0, 0],
                      [0, 1, 0],
                      [1, 1, 1]])
import pprint
pprint.pprint(ans)

#[[0, 0, 0], 
# [0, 1, 0],
# [1, 2, 1]]
posted @ 2020-01-10 22:24  961897  阅读(223)  评论(0编辑  收藏  举报