数据结构与算法学习(4)——二叉树
题目
PS:下列题目均来自leetcode中灵神题单
class Solution:
def rangeSumBST(self, root: TreeNode, low: int, high: int) -> int:
if not root:
return 0
if root.val > high:
return self.rangeSumBST(root.left, low, high)
if root.val < low:
return self.rangeSumBST(root.right, low, high)
return root.val + self.rangeSumBST(root.left, low, high) + self.rangeSumBST(root.right, low, high)
class Solution:
def amountOfTime(self, root: Optional[TreeNode], start: int) -> int:
G=defaultdict(list)
def dfs(root):
if root:
if root.left:
G[root.val].append(root.left.val)
G[root.left.val].append(root.val)
dfs(root.left)
if root.right:
G[root.val].append(root.right.val)
G[root.right.val].append(root.val)
dfs(root.right)
dfs(root)
q = deque([[start, 0]])
vis=set()
vis.add(start)
while q:
val,time=q.popleft()
for around in G[val]:
if around not in vis:
q.append([around, time + 1])
vis.add(around)
return time
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
def search(root,pathval):
if not root:
return False
pathval += root.val
if not root.left and not root.right:
return pathval == targetSum
return search(root.left,pathval) or search(root.right,pathval)
return search(root,0)
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
def search(root,sum):
if not root:
return False
sum-=root.val
if not root.left and not root.right:
if sum==0:
return True
return False
return search(root.left,sum) or search(root.right,sum)
return search(root,targetSum)
"""
我认为比较重要的一个是
if not root.left or not root.right:
return max(left_depth, right_depth)
return min(left_depth, right_depth)
用来判断是不是叶结点
如果not root.left or not root.right那么证明该结点为叶结点或者只有左子节点 or 右子节点
如果该结点为叶结点那么left_depth=right_depth
如果只有左子节点 or 右子节点那么应该是max(left_depth, right_depth)因为此时较小的length不是到叶结点的length而是
当前单子结点的结点的length
"""
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
def dfs(root,length):
if not root:
return length
left_depth = dfs(root.left, length + 1)
right_depth = dfs(root.right, length + 1)
if not root.left or not root.right:
return max(left_depth, right_depth)
return min(left_depth, right_depth)
return dfs(root, 0)
"""
这里的重点是要注意到
if not root.left and not root.right:
return int(path+str(root.val))
这一句,理由是如果去掉这一句的话只保留
if not root:
return apth
那么到达叶结点的结果会被相加两次导致最后的答案是正确结果的两倍
比如对于叶结点node,node.left=null and node.right=null
那么就返回了两次path相加了两次
"""
class Solution:
def sumNumbers(self, root: Optional[TreeNode]) -> int:
def dfs(root,path):
if not root:
return 0
if not root.left and not root.right:
return int(path+str(root.val))
return str(int(dfs(root.left,path+str(root.val)))+int(dfs(root.right,path+str(root.val))))
return int(dfs(root,''))
#BFS
class Solution:
def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode:
queue = deque([cloned])
while queue:
node=queue.popleft()
if node.val==target.val:
return node
else:
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
# 动态规划
"""
对于i个叶子
如果左侧有j(1->i-1)个叶子那么右侧i−j个叶子
注意我们这里遍历是叶子结点因为某一叶结点增加两个叶结点的时候减少了一个
那么总的数量只会增加一个
另外真二叉树的结点个数只会是奇数个
"""
Max=11
ft=[[] for _ in range(Max)]
ft[1]=[TreeNode()]
for i in range(2,Max):
for j in range(1,i):
for left in ft[j]:
for right in ft[i-j]:
ft[i].append(TreeNode(0,left,right))
class Solution:
def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:
return ft[(n + 1) // 2] if n % 2 else []
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
def dfs(dummy):
if not dummy:
return dummy
left=dfs(dummy.left)
right=dfs(dummy.right)
dummy.left,dummy.right=right,left
return dummy
return dfs(root)
class FindElements:
def __init__(self, root: Optional[TreeNode]):
root.val=0
self.queue=deque([root])
self.dummy=root
while self.queue:
node=self.queue.popleft()
if not node.left and not node.right:
continue
v=node.val
if node.left:
node.left.val=2*v+1
self.queue.append(node.left)
if node.right:
node.right.val=2*v+2
self.queue.append(node.right)
def find(self, target: int) -> bool:
def dfs(root):
if not root:
return False
if root.val==target:
return True
return dfs(root.left) or dfs(root.right)
root=self.dummy
return dfs(root)
#优化,在FindElements初始的时候就记录val,而不是重新检索
class FindElements:
def __init__(self, root: Optional[TreeNode]):
root.val=0
self.queue=deque([root])
self.dummy=root
self.p=set()
self.p.add(0)
while self.queue:
node=self.queue.popleft()
if not node.left and not node.right:
continue
v=node.val
if node.left:
node.left.val=2*v+1
self.p.add(node.left.val)
self.queue.append(node.left)
if node.right:
node.right.val=2*v+2
self.p.add(node.right.val)
self.queue.append(node.right)
def find(self, target: int) -> bool:
return target in self.p
class Solution:
def rangeSumBST(self, root: Optional[TreeNode], low: int, high: int) -> int:
queue=deque([root])
res=0
while queue:
node=queue.popleft()
if node.val >=low and node.val<=high:
res+=node.val
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return res
# bisect_left返回的是大于等于该查询值的第一个数,我老是容易记混
class Solution:
def closestNodes(self, root: Optional[TreeNode], queries: List[int]) -> List[List[int]]:
ans=[]
queue=deque([root])
v=[]
while queue:
node=queue.popleft()
v.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
n = len(v)
ans = []
v.sort()
for q in queries:
j = bisect_left(v, q)
mx = v[j] if j < n else -1
if j == n or v[j] != q: # a[j]>q, a[j-1]<q
j -= 1
mn = v[j] if j >= 0 else -1
ans.append([mn, mx])
return ans
#bisect_left
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if a[mid] < x: lo = mid+1
else: hi = mid
return lo
# 注意审题就好,很简单的BFS
def kthLargestLevelSum(self, root: Optional[TreeNode], k: int) -> int:
queue=deque([(root,1)])
res=dict()
while queue:
node,t=queue.popleft()
if node.left:
queue.append((node.left,t+1))
if node.right:
queue.append((node.right,t+1))
if t in res:
res[t]+=node.val
else:
res[t]=node.val
s=sorted(res.items(), key = lambda kv:(kv[1], kv[0]))
if k>len(s):
return -1
return s[-k][1]
不会()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】