Leetcode 刷题笔记 (搜索)
搜索
idea
- dfs 递归
- dfs + 栈
- bfs
- 拓扑排序
dfs模板
#dfs 模板
notice:
1. 判定进入dfs的条件是什么
2. 判定dfs循环内要访问什么
3. 要进入主循环!!!!!!!!
move = [[1,0],[-1,0],[0,1],[0,-1]]
#主循环
for i in range(i): #行
for j in range(j):#列
if 判定条件:
dfs(i,j)
def dfs(i,j,visited):
#1.
if i < 0 or j < 0 or i == len(grid) or j == len(grid[0]) or grid[i][j] == 0:
return 0 # 找1
#2.
if visited[i][j] == 1: #已经访问跳过
reuturn
visited[i][j] = 1 #访问后为1
for di,dj in move:
next_i = di + i
next_j = dj + j
#判断越界
if width > next_i >= 0 and lenth > next_j >= 0 and ...
dfs(next_i,next_j,visited)
695. 岛屿的最大面积(medium)
https://leetcode-cn.com/problems/max-area-of-island/
dfs 递归
class Solution:
def dfs(self, grid, cur_i, cur_j):
if cur_j<0 or cur_i<0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] == 0:
return 0
move = [[1,0],[-1,0],[0,1],[0,-1]]
grid[cur_i][cur_j] = 0
ans = 1
for d_i, d_j in move:
next_i = d_i + cur_i
next_j = d_j + cur_j
ans += self.dfs(grid,next_i,next_j)
return ans
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
for row,val in enumerate(grid):
for column, _ in enumerate(val):
ans = max(ans, self.dfs(grid, row, column))
return ans
dfs 栈
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
move = [[1,0],[-1,0],[0,1],[0,-1]]
for i, val in enumerate(grid):
for j, _ in enumerate(val):
stack = [(i,j)]
cur = 0
while stack:
cur_i, cur_j = stack.pop()
if cur_i < 0 or cur_j < 0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] != 1:
continue
cur += 1
grid[cur_i][cur_j] = 0
for di, dj in move:
next_i,next_j = di+cur_i, dj+cur_j
stack.append((next_i,next_j))
ans = max(cur,ans)
return ans
BFS
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
move = [[1,0],[-1,0],[0,1],[0,-1]]
for i,val in enumerate(grid):
for j, _ in enumerate(val):
queue = [(i,j)]
cur = 0
while queue:
cur_i,cur_j = queue.pop(0)
if cur_i < 0 or cur_j < 0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] != 1:
continue
grid[cur_i][cur_j] = 0
cur += 1
for di,dj in move:
next_i,next_j = cur_i + di,cur_j + dj
queue.append((next_i,next_j))
ans = max(cur,ans)
return ans
934. 最短的桥 (medium)
https://leetcode-cn.com/problems/shortest-bridge/
class Solution:
def shortestBridge(self, grid: List[List[int]]) -> int:
queue = []
move = [[1, 0], [-1, 0], [0, 1], [0, -1]]
def dfs(grid, i, j):
if i < 0 or j < 0 or i == len(grid) or j == len(grid[0]) or grid[i][j] != 1:
return
grid[i][j] = 2
queue.append((i, j))
for di, dj in move:
next_i = i + di
next_j = j + dj
dfs(grid, next_i, next_j)
find = False
for i in range(len(grid)):
for j in range(len(grid[0])):
if not find and grid[i][j] == 1:
dfs(grid, i, j)
find = True
search = 0
while queue:
for _ in range(len(queue)):
cur_i, cur_j = queue.pop(0)
for di, dj in move:
next_i, next_j = cur_i + di, cur_j + dj
if next_i < 0 or next_j < 0 or next_i == len(grid) or next_j == len(grid[0]) or grid[next_i][next_j] == 2:
continue
if grid[next_i][next_j] == 1:
return search
grid[next_i][next_j] = 2
queue.append((next_i, next_j))
search += 1
return search
DFS + BFS
547. 省份数量 (medium)
https://leetcode-cn.com/problems/number-of-provinces/
class Solution:
def findCircleNum(self, isConnected: List[List[int]]) -> int:
def dfs(i):
visited[i] = 1
for j in range(city):
if visited[j] == 0 and isConnected[i][j] == 1:
dfs(j)
city = len(isConnected)
visited = city * [0]
province = 0
for i in range(city):
if visited[i] == 0:
dfs(i)
province += 1
return province
207. 课程表 (medium, 拓扑)
https://leetcode.cn/problems/course-schedule/
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
if prerequisites == []:
return True
adj = [[] for i in range(numCourses)]
in_degree = [0 for _ in range(numCourses)]
for cur, pre in prerequisites:
adj[pre].append(cur)
in_degree[cur] += 1
queue = []
for i in range(numCourses):
if in_degree[i] == 0:
queue.append(i)
while queue:
numCourses -= 1
cur = queue.pop(0)
for i in range(numCourses): #这步的检索啥B了,直接用邻接表查链接的下一个就行了
try:
if in_degree[adj[cur][i]] > 0:
in_degree[adj[cur][i]] -= 1
except:
continue
if in_degree[adj[cur][i]] == 0:
queue.append(adj[cur][i])
return numCourses == 0
- 入度表 BFS
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
if prerequisites == []:
return True
adj = [[] for i in range(numCourses)]
in_degree = [0 for _ in range(numCourses)]
for cur, pre in prerequisites:
adj[pre].append(cur)
in_degree[cur] += 1
queue = []
for i in range(numCourses):
if in_degree[i] == 0:
queue.append(i)
while queue:
numCourses -= 1
cur = queue.pop(0)
for j in adj[cur]:
if in_degree[j] > 0:
in_degree[j] -= 1
if in_degree[j] == 0:
queue.append(j)
return numCourses == 0
- DFS
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
if prerequisites == []:
return True
visited = [0 for _ in range(numCourses)]
def dfs(adj, cur, visited):
if visited[cur] == 1:
return False
if visited[cur] == 2:
return True
visited[cur] = 1
for next_node in adj[cur]:
if not dfs(adj, next_node, visited):
return False
visited[cur] = 2
return True
adj = [[] for i in range(numCourses)]
for cur, pre in prerequisites:
adj[pre].append(cur)
for i in range(numCourses):
if not dfs(adj, i , visited):
return False
return True