日常系列LeetCode《19·BFS 和 DFS》
Posted 常某某的好奇心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日常系列LeetCode《19·BFS 和 DFS》相关的知识,希望对你有一定的参考价值。
数据规模->时间复杂度
<=10^4 😮(n^2)
<=10^7:o(nlogn)
<=10^8:o(n)
10^8<=:o(logn),o(1)
内容
lc 589 :N 叉树的前序遍历
https://leetcode.cn/problems/n-ary-tree-preorder-traversal/
提示:
节点总数在范围 [0, 104]内
0 <= Node.val <= 104
n 叉树的高度小于或等于 1000
进阶:
递归法很简单,你可以使用迭代法完成此题吗?
#方案一:迭代
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def preorder(self, root: 'Node') -> List[int]:
if not root:return []
#
res=[]
stack=list()
stack.append(root)
while stack:
curr=stack.pop()
res.append(curr.val)
#key
for i in range(len(curr.children)-1,-1,-1):
stack.append(curr.children[i])
#
return res
#方案二:递归
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def preorder(self, root: 'Node') -> List[int]:
if not root:return []
#
res=[]
self.dfs(root,res)
return res
def dfs(self,node,res):
if not node:return
res.append(node.val)
#key
for children in node.children:
self.dfs(children,res)
# for i in range(len(node.children)):
# self.dfs(node.children[i],res)
lc 590 :N 叉树的后序遍历
https://leetcode.cn/problems/n-ary-tree-postorder-traversal/
提示:
节点总数在范围 [0, 104] 内
0 <= Node.val <= 104
n 叉树的高度小于或等于 1000
进阶:
递归法很简单,你可以使用迭代法完成此题吗?
#方案一:迭代
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def postorder(self, root: 'Node') -> List[int]:
if not root:return []
res=list()
stack=[] #list()
stack.append(root)
while stack:
curr=stack.pop()
res.append(curr.val)
#
for childnode in curr.children:
stack.append(childnode) #key
res.reverse()
return res
#方案二:递归
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def postorder(self, root: 'Node') -> List[int]:
res=[]
self.dfs(root,res)
return res
def dfs(self,node,res):
if not node:return
#
for child in node.children:
self.dfs(child,res)
res.append(node.val)
lc 429 :N 叉树的层序遍历
https://leetcode.cn/problems/n-ary-tree-level-order-traversal/
提示:
树的高度不会超过 1000
树的节点总数在 [0, 10^4] 之间
#方案一:BFS
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if not root:return []
res=[]
queue=deque()
queue.append(root)
while queue:
level_nodes_val=[]
for i in range(len(queue)):
curr=queue.popleft()
level_nodes_val.append(curr.val) #key
for child in curr.children:
queue.append(child)
res.append(level_nodes_val)
return res
#方案二:DFS
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
res=[]
self.dfs(root,0,res)
return res
def dfs(self,node,currlevel,res):
if not node:return []
#key
if len(res)-1 <currlevel:
res.append([node.val])
else:
res[currlevel].append(node.val)
#
for child in node.children:
self.dfs(child,currlevel+1,res)
lc 690 :员工的重要性
https://leetcode.cn/problems/employee-importance/
提示:
一个员工最多有一个 直系 领导,但是可以有多个 直系 下属
员工数量不超过 2000 。
#方案一:DFS-前序
"""
# Definition for Employee.
class Employee:
def __init__(self, id: int, importance: int, subordinates: List[int]):
self.id = id
self.importance = importance
self.subordinates = subordinates
"""
class Solution:
def getImportance(self, employees: List['Employee'], id: int) -> int:
self.id_map=emp.id:emp for emp in employees #key:id-emp
self.total=0 #key
self.dfs(id)
return self.total
def dfs(self,id):
emp=self.id_map[id]
if not emp:return
#
self.total+=emp.importance
#
for sub_emp_id in emp.subordinates:
self.dfs(sub_emp_id)
#方案二:DFS-后序
"""
# Definition for Employee.
class Employee:
def __init__(self, id: int, importance: int, subordinates: List[int]):
self.id = id
self.importance = importance
self.subordinates = subordinates
"""
class Solution:
def getImportance(self, employees: List['Employee'], id: int) -> int:
self.id_map=emp.id:emp for emp in employees #key:id-emp
return self.dfs(id)
def dfs(self,id):
emp=self.id_map[id]
if not emp:return 0
#dfs的时候(self.total=0)先累加子节点值,最后在加根节点(root.importance)
self.total=0 #key:注意位置,
for sub_emp_id in emp.subordinates:
self.total+=self.dfs(sub_emp_id)
return emp.importance+self.total
#方案三:BFS
"""
# Definition for Employee.
class Employee:
def __init__(self, id: int, importance: int, subordinates: List[int]):
self.id = id
self.importance = importance
self.subordinates = subordinates
"""
class Solution:
def getImportance(self, employees: List['Employee'], id: int) -> int:
self.id_map=emp.id:emp for emp in employees #key:id-emp
return self.bfs(id)
def bfs(self,id):
emp=self.id_map[id]
if not emp:return 0
#
res=0
queue=deque()
queue.append(emp)
while queue:
levelres=0
for i in range(len(queue)):
curr=queue.popleft()
levelres+=curr.importance
for sub_id in curr.subordinates:
queue.append(self.id_map[sub_id]) #key
res+=levelres
return res
图的 DFS 和 BFS:key-遍历过程中,设置节点访问
floodfill 算法基础
#数组二维转一维
#数组一维转二维度
#二维数组的四联通
#二维数组的八联通
#保证索引访问合法
lc 733 :图像渲染
https://leetcode.cn/problems/flood-fill/
提示:
m == image.length
n == image[i].length
1 <= m, n <= 50
0 <= image[i][j], newColor < 216
0 <= sr < m
0 <= sc < n
#方案一:DFS
class Solution:
def floodFill(self, image: List[List[int]], sr: int, sc: int, color: int) -> List[List[int]]:
self.dirs=[[-1,0],[1,0],[0,-1],[0,1]]
self.image=image
self.visited=[[False]*len(self.image[0]) for _ in range(len(self.image))]
self.oldcolor=self.image[sr][sc]
self.dfs(sr,sc,color)
return image
def inarea(self,row,col):
return row>=0 and row<len(self.image) and col>=0 and col<len(self.image[0])
def dfs(self,row,col,newcolor):
#终止条件
if not self.inarea(row,col) or self.image[row][col]!=self.oldcolor:
return
#
self.image[row][col]=newcolor
self.visited[row][col]=True
for dir in self.dirs:
next_row=row+dir[0]
next_col=col+dir[1]
if self.inarea(next_row,next_col):
if not self.visited[next_row][next_col]:
self.dfs(next_row,next_col,newcolor)
#方案二:BFS
class Solution:
def floodFill(self, image: List[List[int]], sr: int, sc: int, color: int) -> List[List[int]]:
self.image=image
self.old_color=image[sr][sc]
if self.old_color == color: #key
return image
self.dirs=[[0,1],[0,-1],[1,0],[-1,0]]
self.bfs(sr,sc,color)
return self.image
def inarea(self,row,col):
return row>=0 and row<len(self.image) and col>=0 and col<len(self.image[0])
def bfs(self,row,col,newcolor):
queue=deque()
queue.append([row,col])
self.image[row][col]=newcolor
while queue:
curr=queue.popleft()
#
for dir in self.dirs: #key1
nextrow=dir[0]+curr[0]
nextcol=dir[1]+curr[1]
if self.inarea(nextrow,nextcol) and self.image[nextrow][nextcol]==self.old_color:
queue.append([nextrow,nextcol]) #key1
self.image[nextrow][nextcol]=newcolor
lc 463 :岛屿的周长
https://leetcode.cn/problems/island-perimeter/
提示:
row == grid.length
col == grid[i].length
1 <= row, col <= 100
grid[i][j] 为 0 或 1
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连(只有一个岛)
#方案一:DFS-前序
class Solution:
def islandPerimeter(self, grid: List[List[int]]) -> int:
self.grid=grid
self.dirs=[[-1,0],[1,0],[0,-1],[0,1]]
self.visited=[[False]*len(grid[0]) for _ in range(len(grid))]
#
self.ans=0
for i in range(len(self.grid)):
for j in range(len(self.grid[0])):
if self.grid[i][j]==1:
self.dfs(i,j)
return self.ans
def inarea(self,row,col):
return row>=0 and row<len(self.grid) and col>=0 and col<len(self.grid[0])
def dfs(self,row,col):
if not self.inarea(row,col) or self.grid[row][col]==0 or self.visited[row][col]:
return
#
self.visited[row][col]=True
for dir in self.dirs:
nextrow=dir[0]+row
nextcol=dir[1]+col
#key:计边长
if not self.inarea(nextrow,nextcol) or self.grid[nextrow][nextcol]==0:
self.ans+=1
elif not self.visited[nextrow][nextcol]:
self.dfs(nextrow,nextcol)
#方案二:DFS-后序
class Solution:
def islandPerimeter(self, grid: List[List[int]]) -> int:
self.grid=grid
self.dirs=[[-1,0],[1,0],[0,-1],[0,1]]
self.visited=[[False]*len(grid[0]) for _ in range(len(grid))]
#
for i in range(len(self.grid)):
for j in range(len(self.grid[0])):
if self.grid[i][j]==以上是关于日常系列LeetCode《19·BFS 和 DFS》的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 1302 层数最深叶子节点的和[BFS DFS] HERODING的LeetCode之路