题目描述:
A virus is spreading rapidly, and your task is to quarantine the infected area by installing walls.
The world is modeled as a 2-D array of cells, where 0
represents uninfected cells, and 1
represents cells contaminated with the virus. A wall (and only one wall) can be installed between any two 4-directionally adjacent cells, on the shared boundary.
Every night, the virus spreads to all neighboring cells in all four directions unless blocked by a wall. Resources are limited. Each day, you can install walls around only one region -- the affected area (continuous block of infected cells) that threatens the most uninfected cells the following night. There will never be a tie.
Can you save the day? If so, what is the number of walls required? If not, and the world becomes fully infected, return the number of walls used.
Example 1:
Input: grid = [[0,1,0,0,0,0,0,1], [0,1,0,0,0,0,0,1], [0,0,0,0,0,0,0,1], [0,0,0,0,0,0,0,0]] Output: 10 Explanation: There are 2 contaminated regions. On the first day, add 5 walls to quarantine the viral region on the left. The board after the virus spreads is: [[0,1,0,0,0,0,1,1], [0,1,0,0,0,0,1,1], [0,0,0,0,0,0,1,1], [0,0,0,0,0,0,0,1]] On the second day, add 5 walls to quarantine the viral region on the right. The virus is fully contained.
Example 2:
Input: grid = [[1,1,1], [1,0,1], [1,1,1]] Output: 4 Explanation: Even though there is only one cell saved, there are 4 walls built. Notice that walls are only built on the shared boundary of two different cells.
Example 3:
Input: grid = [[1,1,1,0,0,0,0,0,0], [1,0,1,0,1,1,1,1,1], [1,1,1,0,0,0,0,0,0]] Output: 13 Explanation: The region on the left only builds two new walls.
Note:
- The number of rows and columns of
grid
will each be in the range[1, 50]
. - Each
grid[i][j]
will be either0
or1
. - Throughout the described process, there is always a contiguous viral region that will infect strictly more uncontaminated squares in the next round.
题目描述:
二维矩阵grid表示一组细胞,1表示病毒感染的细胞,0表示正常细胞。
病毒感染的细胞会感染其邻近细胞,为防止病毒扩散,每一天在受影响最多的细胞周围设立“隔离墙”。
求最终会设立多少隔离墙。
解题思路:
BFS(广度优先搜索)
Python代码:
class Solution(object):
def containVirus(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
m, n = len(grid), len(grid[0])
stop = False
allCellWalls = collections.defaultdict(set)
while not stop:
stop = True
quarantineNeighbors = dict()
surroundedViruses = set()
visitedCells = set()
affectedCells = set()
for x in range(m):
for y in range(n):
if grid[x][y] > 0 and (x, y) not in visitedCells:
stop = False
cellWalls, virusCells = self.cellWalls(grid, x, y, m, n)
if not quarantineNeighbors or len(cellWalls.keys()) > len(quarantineNeighbors.keys()):
quarantineNeighbors = cellWalls
surroundedViruses = virusCells
affectedCells |= set(cellWalls.keys())
visitedCells |= virusCells
for key in quarantineNeighbors: allCellWalls[key] |= quarantineNeighbors[key]
confirmInfectedCells = []
for x, y in affectedCells:
for idx, (dx, dy) in enumerate(zip([0, -1, 0, 1], [-1, 0, 1, 0])):
nx = x + dx
ny = y + dy
if 0 <= nx < m and 0 <= ny < n:
if grid[nx][ny] > 0 and idx not in allCellWalls[(x, y)]:
confirmInfectedCells.append((x, y))
break
for x, y in confirmInfectedCells: grid[x][y] = 1
for x, y in surroundedViruses: grid[x][y] = -1
return sum(len(v) for v in allCellWalls.values())
def cellWalls(self, grid, x, y, m, n):
queue = [[x, y]]
cellWalls = collections.defaultdict(set)
virusCells = set([(x, y)])
walls = 0
while queue:
px, py = queue.pop(0)
for idx, (dx, dy) in enumerate(zip([0, 1, 0, -1], [1, 0, -1, 0])):
nx = px + dx
ny = py + dy
if 0 <= nx < m and 0 <= ny < n:
if grid[nx][ny] == 0:
cellWalls[(nx, ny)].add(idx)
elif (nx, ny) not in virusCells and grid[nx][ny] > 0:
queue.append((nx, ny))
virusCells.add((nx, ny))
return cellWalls, virusCells
本文链接:http://bookshadow.com/weblog/2017/12/17/leetcode-contain-virus/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。