【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]]

原文地址:https://www.cnblogs.com/ldy-miss/p/12178393.html

时间: 2024-11-08 12:49:37

【Leetcode 广搜、动态规划】01 矩阵(542)的相关文章

Leetcode 542:01 矩阵 01

Leetcode 542:01 矩阵 01 Matrix### 题目: 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. The distance between two adjacent cells is 1. 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出

LeetCode——542. 01 矩阵

给定一个由 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的点都存入queue,将

Leetcode 542.01矩阵

01矩阵 给定一个由 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入队,把1置为MAX_VALUE,然

leetcode 深搜广搜

遍历整个grid数组,当发现有1的时候,就把和这个1连成片的1都置为0,并增加一个计数.最后返回这个计数. 广搜,但这个代码通不过测试,栈溢出. class Solution { public: void bfs(vector<vector<char>>& grid,int i,int j){ if(i<0||j<0||i>=grid.size()||j>=grid[0].size()) return; if(grid[i][j]=='0') ret

leetcode Word Ladder 广搜

利用两个队列(或vector):curlevel和nextlvevl分别表示当前层的所有可能状态和转换到的下一层的所有可能状态.我们的目标是转换到end单词即可,深搜会超时.使用广搜,各层的可能结点同时向下进行,找到end即可return.当找完当前层的所有可能结点后,当前层也就空了,然后swap(当前层,下一层)循环向下搜索. 下面两个代码都是用这个方法,第一个超时,使用第二段代码,对于每个结点,只需找25*len种下一个可能结点是否存在,第一段代码需要在大数据里慢慢找. note:在一个字符

poj1111 Image Perimeters 广搜

题目大意: 输入一个矩阵,再输入其中一个“X”的位置(从1开始).从该位置向八个方向扩展,如果是“X”就可以并在一起.问最后得到的模块的周长是多少. 解题思路: 按照广搜的思路来做.用一个二维的数组标记每一个点,-1代表着该点不能被搜索了(可能原本就是“.”,也可以该点已经出队列了):0代表着该点还没被搜到:1代表着该点已经被搜到,但是还在队列中. 初始周长为4,代表只有一个X时的周长.对于每一个点,如果是“X”,就初始化为标记为0:如果是"."就初始化为-1. 对于当前进行搜索的X的

HNU 10111 0-1矩阵

http://acm.hnu.cn/online/?action=problem&type=show&id=10111 题意:中文 题解:在龙哥的帮助下正了二分图匹配的三观--以前的理解繁琐,或者有点儿错吧--二分图匹配从左往右匹配,找增广路.顶点数和match()不需要那么麻烦. 1 // 2 // main.cpp 3 // POJ 3041 4 // 5 // Created by zhang on 14-4-16. 6 // Copyright (c) 2014年 apple. A

hdu5335 Walk Out (递推||广搜)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5335 题意:给你N*M的01矩阵,求从(1,1)位置走到(N,M)的最小二进制数,输出不含前导0. 分析:为了不让当前位置向上走,可以先将所有的起点预处理出来.当(1,1)为1,那么起点只有一个,就是(1,1);当(1,1)为0,起点就是从(1,1)可达的并且只走0的这些点,然后把这些起点离终点最近的所有点选出来,那么这些起点在一条斜线上,而且只能向右或者向下走.然后在斜线上递推,有0可走就只走0,否则

nyoj 999——师傅又被妖怪抓走了——————【双广搜】

师傅又被妖怪抓走了 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 话说唐僧复得了孙行者,师徒们一心同体,共诣西方.自宝象国救了公主,承君臣送出城西,沿路饥餐渴饮,悟空便为师傅去化斋,等悟空回来,悟净慌慌张张的对悟空说:“不好了,不好了”,还没等悟净说完,悟空说:“师傅又被妖怪抓走了”,悟净:“NO!” ,悟空一脸茫然,悟净:“师傅和二师兄都被妖怪抓走了”.悟空(晕!).为了防止悟空救人,妖怪先把唐憎和八戒分别藏起来,如果悟空在T分钟之后还没找到人,那必定是被妖怪吃