すのはら荘春原庄的雪

数据结构与算法学习(4)——二叉树

zzddkk·2024-05-28 22:59·7 次阅读

数据结构与算法学习(4)——二叉树

题目

PS:下列题目均来自leetcode中灵神题单

938. 二叉搜索树的范围和

Copy
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)

2385. 感染二叉树需要的总时间

Copy
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

112. 路径总和

Copy
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)
Copy
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)

111. 二叉树的最小深度

Copy
""" 我认为比较重要的一个是 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)

129. 求根节点到叶节点数字之和

Copy
""" 这里的重点是要注意到 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,''))

1379. 找出克隆二叉树中的相同节点

Copy
#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)

894. 所有可能的真二叉树

Copy
# 动态规划 """ 对于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 []

226. 翻转二叉树

Copy
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)

1261. 在受污染的二叉树中查找元素

Copy
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)
Copy
#优化,在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

938. 二叉搜索树的范围和

Copy
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

2476. 二叉搜索树最近节点查询

Copy
# 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
Copy
#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

2583. 二叉树中的第 K 大层和

Copy
# 注意审题就好,很简单的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]

889. 根据前序和后序遍历构造二叉树

Copy
不会()
posted @   zddkk  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示