841. Keys and Rooms
There are n
rooms labeled from 0
to n - 1
and all the rooms are locked except for room 0
. Your goal is to visit all the rooms. However, you cannot enter a locked room without having its key.
When you visit a room, you may find a set of distinct keys in it. Each key has a number on it, denoting which room it unlocks, and you can take all of them with you to unlock the other rooms.
Given an array rooms
where rooms[i]
is the set of keys that you can obtain if you visited room i
, return true
if you can visit all the rooms, or false
otherwise.
BFS:
class Solution:
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
self.visited = [False] * len(rooms)
self.dfs(rooms, 0)
for i in range(len(rooms)):
if not self.visited[i]:
return False
return True
def dfs(self, rooms, key):
if self.visited[key]:
return
self.visited[key] = True
keys = rooms[key]
for i in range(len(keys)):
self.dfs(rooms,keys[i])
DFS:
class Solution:
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
self.visited = [False] * len(rooms)
self.bfs(rooms, 0)
for i in range(len(rooms)):
if not self.visited[i]:
return False
return True
def bfs(self, rooms, key):
q = collections.deque([key])
self.visited[0] = True
while q:
idx = q.popleft()
for key in rooms[idx]:
if not self.visited[key]:
q.append(key)
self.visited[key] = True
#self.bfs(rooms, key) bfs不需要这recursion 因为deque每次循环都append,加了也没问题
127. Word Ladder
A transformation sequence from word beginWord
to word endWord
using a dictionary wordList
is a sequence of words beginWord -> s1 -> s2 -> ... -> sk
such that:
si
for 1 <= i <= k
is in wordList
. Note that beginWord
does not need to be in wordList
.sk == endWord
Given two words, beginWord
and endWord
, and a dictionary wordList
, return the number of words in the shortest transformation sequence from beginWord
to endWord
, or 0
if no such sequence exists.
BFS:
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
wordSet = set(wordList)
if len(wordSet)== 0 or endWord not in wordSet:
return 0
mapping = {beginWord:1}
queue = deque([beginWord])
while queue:
word = queue.popleft()
path = mapping[word]
for i in range(len(word)):
word_list = list(word)
for j in range(26):
word_list[i] = chr(ord('a')+j)
newWord = "".join(word_list)
if newWord == endWord:
return path+1
if newWord in wordSet and newWord not in mapping:
mapping[newWord] = path+1
queue.append(newWord)
return 0
827. Making A Large Island
You are given an n x n
binary matrix grid
. You are allowed to change at most one 0
to be 1
.
Return the size of the largest island in grid
after applying this operation.
An island is a 4-directionally connected group of 1
s.
class Solution:
def largestIsland(self, grid: List[List[int]]) -> int:
visited = set() #标记访问过的位置
m, n = len(grid), len(grid[0])
res = 0
island_size = 0 #用于保存当前岛屿的尺寸
directions = [[0, 1], [0, -1], [1, 0], [-1, 0]] #四个方向
islands_size = defaultdict(int) #保存每个岛屿的尺寸
def dfs(island_num, r, c):
visited.add((r, c))
grid[r][c] = island_num #访问过的位置标记为岛屿编号
nonlocal island_size
island_size += 1
for i in range(4):
nextR = r + directions[i][0]
nextC = c + directions[i][1]
if (nextR not in range(m) or #行坐标越界
nextC not in range(n) or #列坐标越界
(nextR, nextC) in visited): #坐标已访问
continue
if grid[nextR][nextC] == 1: #遇到有效坐标,进入下一个层搜索
dfs(island_num, nextR, nextC)
island_num = 2 #初始岛屿编号设为2, 因为grid里的数据有0和1, 所以从2开始编号
all_land = True #标记是否整个地图都是陆地
for r in range(m):
for c in range(n):
if grid[r][c] == 0:
all_land = False #地图里不全是陆地
if (r, c) not in visited and grid[r][c] == 1:
island_size = 0 #遍历每个位置前重置岛屿尺寸为0
dfs(island_num, r, c)
islands_size[island_num] = island_size #保存当前岛屿尺寸
island_num += 1 #下一个岛屿编号加一
if all_land:
return m * n #如果全是陆地, 返回地图面积
count = 0 #某个位置0变成1后当前岛屿尺寸
#因为后续计算岛屿面积要往四个方向遍历,但某2个或3个方向的位置可能同属于一个岛,
#所以为避免重复累加,把已经访问过的岛屿编号加入到这个集合
visited_island = set() #保存访问过的岛屿
for r in range(m):
for c in range(n):
if grid[r][c] == 0:
count = 1 #把由0转换为1的位置计算到面积里
visited_island.clear() #遍历每个位置前清空集合
for i in range(4):
nearR = r + directions[i][0]
nearC = c + directions[i][1]
if nearR not in range(m) or nearC not in range(n): #周围位置越界
continue
if grid[nearR][nearC] in visited_island: #岛屿已访问
continue
count += islands_size[grid[nearR][nearC]] #累加连在一起的岛屿面积
visited_island.add(grid[nearR][nearC]) #标记当前岛屿已访问
res = max(res, count)
return res