目录
286. 墙与门
https://leetcode-cn.com/problems/walls-and-gates/
你被给定一个 m × n 的二维网格,网格中有以下三种可能的初始化值:
-1 表示墙或是障碍物
0 表示一扇门
INF 无限表示一个空的房间。然后,我们用 231 - 1 = 2147483647 代表 INF。你可以认为通往门的距离总是小于 2147483647 的。
你要给每个空房间位上填上该房间到 最近 门的距离,如果无法到达门,则填 INF 即可。
示例:
给定二维网格:
INF -1 0 INF
INF INF INF -1
INF -1 INF -1
0 -1 INF INF
运行完你的函数后,该网格应该变成:
3 -1 0 1
2 2 1 -1
1 -1 2 -1
0 -1 3 4
题解
一:从空房间出发,广度优先遍历寻找距每一个空房间最近的门(寻找的过程O(mn)), 每一个空房间都要做一次广度遍历,需要O(mn)的广度遍历,最终的时间复杂度O(m^2n^2)。
二:从门出发,先遍历一遍数组将所有的门入队。从门开始做广度遍历,每个空房间只要遍历一遍,时间复杂度O(mn)。由于宽度优先搜索保证我们在搜索 d + 1 距离的位置时, 距离为 d 的位置都已经被搜索过了,所以到达每一个房间的时候都一定是最短距离。
from collections import deque
class Solution(object):
def wallsAndGates(self, rooms):
"""
:type rooms: List[List[int]]
:rtype: None Do not return anything, modify rooms in-place instead.
"""
def inArea(i, j, m, n):
return 0 <= i < m and 0 <= j < n
if not rooms or not rooms[0]:
return
m, n = len(rooms), len(rooms[0])
visited = [[False] * n for _ in range(m)]
q = deque()
for i in range(m):
for j in range(n):
if rooms[i][j] == 0:
q.append([i, j])
visited[i][j] = True
pos = [[0, 1], [1, 0], [0, -1], [-1, 0]]
dis = 1
while q:
length = len(q)
for i in range(length):
idx, idy = q.popleft()
for j in range(4):
newx, newy = idx + pos[j][0], idy + pos[j][1]
if (inArea(newx, newy, m, n) and rooms[newx][newy] > 0
and not visited[newx][newy]):
visited[newx][newy] = True
q.append([newx, newy])
rooms[newx][newy] = dis
dis += 1
return
1254. 统计封闭岛屿的数目
https://leetcode-cn.com/problems/number-of-closed-islands/
有一个二维矩阵 grid ,每个位置要么是陆地(记号为 0 )要么是水域(记号为 1 )。
我们从一块陆地出发,每次可以往上下左右 4 个方向相邻区域走,能走到的所有陆地区域,我们将其称为一座「岛屿」。
如果一座岛屿 完全 由水域包围,即陆地边缘上下左右所有相邻区域都是水域,那么我们将其称为 「封闭岛屿」。
请返回封闭岛屿的数目。
示例 1:
输入:grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]
输出:2,解释:灰色区域的岛屿是封闭岛屿,因为这座岛屿完全被水域包围(即被 1 区域包围)。
示例 2:
输入:grid = [[0,0,1,0,0],[0,1,0,1,0],[0,1,1,1,0]]
输出:1
示例 3:
输入:grid = [[1,1,1,1,1,1,1],
[1,0,0,0,0,0,1],
[1,0,1,1,1,0,1],
[1,0,1,0,1,0,1],
[1,0,1,1,1,0,1],
[1,0,0,0,0,0,1],
[1,1,1,1,1,1,1]]
输出:2
提示:
1 <= grid.length, grid[0].length <= 100
0 <= grid[i][j] <=1
题解
一:DFS
class Solution(object):
def closedIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
def valid(i, j, m, n):
return 0 <= i < m and 0 <= j < n
def dfs(i, j, grid, m, n):
if not valid(i, j, m, n):
return False
if grid[i][j] == 1:
return True
grid[i][j] = 1
up = dfs(i-1,j,grid, m, n);
down = dfs(i+1,j,grid, m, n);
left = dfs(i,j-1,grid, m, n);
right = dfs(i,j+1,grid, m, n);
if(up and down and left and right):
return True
return False
if not grid or not grid[0]:
return 0
m, n = len(grid), len(grid[0])
pos = [[0, 1], [1, 0], [0, -1], [-1, 0]]
ans = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 0:
if dfs(i, j, grid, m, n):
ans += 1
# print(used)
return ans