from collections import deque
from typing import List, Optional
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class SolutionPreorderTraversal:
"""二叉树的递归遍历"""
def preorderTraversal(self, root: TreeNode) -> List[int]:
# 保存结果
result = []
def traversal(root: TreeNode):
if root == None:
return
result.append(root.val) # 前序
traversal(root.left) # 左
traversal(root.right) # 右
traversal(root)
return result
# 中序遍历-递归-LC94_二叉树的中序遍历
class SolutionInorderTraversal:
def inorderTraversal(self, root: TreeNode) -> List[int]:
result = []
def traversal(root: TreeNode):
if root == None:
return
traversal(root.left) # 左
result.append(root.val) # 中序
traversal(root.right) # 右
traversal(root)
return result
# 后序遍历-递归-LC145_二叉树的后序遍历
class SolutionPostorderTraversal:
def postorderTraversal(self, root: TreeNode) -> List[int]:
result = []
def traversal(root: TreeNode):
if root == None:
return
traversal(root.left) # 左
traversal(root.right) # 右
result.append(root.val) # 后序
traversal(root)
return result
class SolutionLevelOrder:
"""二叉树层序遍历"""
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
res = []
if not root:
return res
from collections import deque
queue = deque([root])
while queue:
size = len(queue)
sig_res = []
for _ in range(size):
tmp = queue.popleft()
sig_res.append(tmp.val)
if tmp.left:
queue.append(tmp.left)
if tmp.right:
queue.append(tmp.right)
res.append(sig_res)
return res
class SolutionInvertTree:
"""翻转二叉树"""
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
root.left, root.right = root.right, root.left # 中
self.invertTree(root.left) # 左
self.invertTree(root.right) # 右
return root
class SolutionIsSymmetric:
"""对称二叉树"""
def isSymmetric(self, root: TreeNode) -> bool:
if not root:
return True
return self.compare(root.left, root.right)
def compare(self, left, right):
# 首先排除空节点的情况
if left == None and right != None:
return False
elif left != None and right == None:
return False
elif left == None and right == None:
return True
# 排除了空节点,再排除数值不相同的情况
elif left.val != right.val:
return False
# 此时就是:左右节点都不为空,且数值相同的情况
# 此时才做递归,做下一层的判断
outside = self.compare(left.left, right.right) # 左子树:左、 右子树:右
inside = self.compare(left.right, right.left) # 左子树:右、 右子树:左
isSame = outside and inside # 左子树:中、 右子树:中 (逻辑处理)
return isSame
class solutionMaxdepth:
"""二叉树的最大深度"""
def maxdepth(self, root) -> int:
return self.getdepth(root)
def getdepth(self, node):
if not node:
return 0
leftheight = self.getdepth(node.left) # 左
rightheight = self.getdepth(node.right) # 右
height = 1 + max(leftheight, rightheight) # 中
return height
class SolutionMinDepth:
"""二叉树的最小深度"""
def minDepth(self, root: TreeNode) -> int:
if not root:
return 0
if not root.left and not root.right:
return 1
min_depth = 10 ** 9
if root.left:
min_depth = min(self.minDepth(root.left), min_depth) # 获得左子树的最小高度
if root.right:
min_depth = min(self.minDepth(root.right), min_depth) # 获得右子树的最小高度
return min_depth + 1
class SolutionCountNodes:
"""完全二叉树的节点个数"""
def countNodes(self, root: TreeNode) -> int:
return self.getNodesNum(root)
def getNodesNum(self, cur):
if not cur:
return 0
leftNum = self.getNodesNum(cur.left) # 左
rightNum = self.getNodesNum(cur.right) # 右
treeNum = leftNum + rightNum + 1 # 中
return treeNum
class SolutionIsBalanced:
"""平衡二叉树"""
def isBalanced(self, root: TreeNode) -> bool:
if self.get_height(root) != -1:
return True
else:
return False
def get_height(self, root: TreeNode) -> int:
# Base Case
if not root:
return 0
# 左
if (left_height := self.get_height(root.left)) == -1:
return -1
# 右
if (right_height := self.get_height(root.right)) == -1:
return -1
# 中
if abs(left_height - right_height) > 1:
return -1
else:
return 1 + max(left_height, right_height)
class SolutionBinaryTreePaths:
"""二叉树的所有路径"""
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
res = []
path = []
def trans(current_node):
path.append(current_node.val)
if current_node.left is None and current_node.right is None:
res.append("->".join([str(i) for i in path[:]]))
if current_node.left:
trans(current_node.left)
path.pop()
if current_node.right:
trans(current_node.right)
path.pop()
trans(root)
return res
class SolutionSumOfLeftLeaves:
"""左叶子之和"""
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
left_sum = self.sumOfLeftLeaves(root.left)
if root.left and root.left.left is None and root.left.right is None:
left_sum = root.left.val
right_sum = self.sumOfLeftLeaves(root.right)
return left_sum + right_sum
class SolutionFindBottomLeftValue:
"""找树左下角的值"""
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
queue = deque([root])
if root is None:
return []
while queue:
temp = []
size = len(queue)
for i in range(size):
current_node = queue.popleft()
temp.append(current_node.val)
if current_node.left:
queue.append(current_node.left)
if current_node.right:
queue.append(current_node.right)
res = temp[0]
return res
class SolutionHasPathSum:
"""路径总和"""
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
res = []
path = []
if not root:
return False
def trans(root, targetSum):
path.append(root.val)
if root.left is None and root.right is None:
if sum(path) == targetSum:
res.append(path[:])
if root.left:
trans(root.left, targetSum)
path.pop()
if root.right:
trans(root.right, targetSum)
path.pop()
trans(root, targetSum)
return True if res else False
class SolutionBuildTree:
"""从中序与后序遍历序列构造二叉树"""
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
# 第一步: 特殊情况讨论: 树为空. 或者说是递归终止条件
if not preorder:
return None
# 第二步: 前序遍历的第一个就是当前的中间节点.
root_val = preorder[0]
root = TreeNode(root_val)
# 第三步: 找切割点.
separator_idx = inorder.index(root_val)
# 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
inorder_left = inorder[:separator_idx]
inorder_right = inorder[separator_idx + 1:]
# 第五步: 切割preorder数组. 得到preorder数组的左,右半边.
# ⭐️ 重点1: 中序数组大小一定跟前序数组大小是相同的.
preorder_left = preorder[1:1 + len(inorder_left)]
preorder_right = preorder[1 + len(inorder_left):]
# 第六步: 递归
root.left = self.buildTree(preorder_left, inorder_left)
root.right = self.buildTree(preorder_right, inorder_right)
return root
class SolutionConstructMaximumBinaryTree:
"""最大二叉树"""
def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
if not nums:
return None
max_val = max(nums)
index_max = nums.index(max_val)
root = TreeNode(max_val)
left_tree_list = nums[:index_max]
right_tree_list = nums[index_max + 1:]
root.left = self.constructMaximumBinaryTree(left_tree_list)
root.right = self.constructMaximumBinaryTree(right_tree_list)
return root
class SolutionMergeTrees:
"""合并二叉树"""
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
# 递归终止条件:
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
if not root1:
return root2
if not root2:
return root1
# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
root1.val += root2.val # 中
root1.left = self.mergeTrees(root1.left, root2.left) # 左
root1.right = self.mergeTrees(root1.right, root2.right) # 右
return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.
class SolutionSearchBST:
"""二叉搜索树中的搜索"""
def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
def trans(current_node, val):
if current_node is None:
return None
if current_node.val == val:
return current_node
node1 = trans(current_node.left, val)
node2 = trans(current_node.right, val)
if node1:
return node1
elif node2:
return node2
else:
return None
res = trans(root, val)
return res
class SolutionIsValidBST:
"""是否是有效二叉搜索树"""
def isValidBST(self, root: Optional[TreeNode]) -> bool:
res = []
def trans(root, res):
if not root:
return
trans(root.left, res)
res.append(root.val)
trans(root.right, res)
trans(root, res)
return res == sorted(res) and len(res) == len(set(res))
class SolutionGetMinimumDifference:
"""二叉搜索树的最小绝对差"""
def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
def trans(root, res):
if not root:
return
res.append(root.val)
trans(root.left, res)
trans(root.right, res)
res = []
trans(root, res)
res.sort()
min_val = res[1] - res[0]
for i in range(1, len(res)):
temp = abs(res[i] - res[i - 1])
min_val = min(min_val, temp)
return min_val
class SolutionFindMode:
"""二叉搜索树中的众数"""
def findMode(self, root: Optional[TreeNode]):
res = []
def trans(root, res):
if not root:
return
res.append(root.val)
trans(root.left, res)
trans(root.right, res)
trans(root, res)
from collections import Counter
cnt = Counter(res)
max_num = cnt.most_common(1)[0][1]
result = []
for key, item in cnt.items():
if item == max_num:
result.append(key)
return result
class SolutionLowestCommonAncestor:
""" 二叉树的最近公共祖先"""
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
def trans(root, p, q):
if root is None:
return None
if root == p or root == q:
return root
node_left = trans(root.left, p, q)
node_right = trans(root.right, p, q)
if node_left and node_right:
return root
if node_left and not node_right:
return node_left
if not node_left and node_right:
return node_right
else:
return None
node = trans(root, p, q)
return node
class SolutionLowestCommonAncestor:
"""二叉搜索树的最近公共祖先"""
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
def trans(root, p, q):
if root is None:
return None
if root.val > q.val and root.val > p.val:
return trans(root.left, p, q)
if root.val < q.val and root.val < p.val:
return trans(root.right, p, q)
return root
node = trans(root, p, q)
return node
class SolutionInsertIntoBST:
"""二叉搜索树中的插入操作"""
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root is None:
return TreeNode(val)
if root.val > val:
root.left = self.insertIntoBST(root.left, val)
if root.val < val:
root.right = self.insertIntoBST(root.right, val)
return root
class SolutionDeleteNode:
"""删除二叉树"""
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
def trans(current_node, key):
if not current_node:
return None
if current_node.val == key:
if current_node.left is None and current_node.right is None:
return None
elif current_node.left and not current_node.right:
return current_node.left
elif current_node.right and not current_node.left:
return current_node.right
else:
cur = current_node.right
while cur.left:
cur = cur.left
cur.left = current_node.left
return current_node.right
if current_node.val > key:
current_node.left = trans(current_node.left, key)
if current_node.val < key:
current_node.right = trans(current_node.right, key)
return current_node
res = trans(root, key)
return res
class SolutionTrimBST:
"""修剪二叉树"""
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
def trans(current_node, low, high):
if not current_node:
return None
if current_node.val < low:
return trans(current_node.right, low, high)
if current_node.val > high:
return trans(current_node.left, low, high)
current_node.left = trans(current_node.left, low, high)
current_node.right = trans(current_node.right, low, high)
return current_node
res = trans(root, low, high)
return res
class SolutionSortedArrayToBST:
"""将有序数组转换为二叉搜索树"""
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
def trans(nums, left, right):
if left > right:
return None
mid = (left + right) // 2
root = TreeNode(nums[mid])
root.left = trans(nums, left, mid - 1)
root.right = trans(nums, mid + 1, right)
return root
res = trans(nums, 0, len(nums) - 1)
return res
class SolutionConvertBST:
"""把二叉搜索树转换为累加树"""
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
pre = 0
def trans(root):
nonlocal pre
if not root:
return
trans(root.right)
root.val += pre
pre = root.val
trans(root.left)
trans(root)
return root
leetcode二叉树相关题型python实现
最新推荐文章于 2024-08-21 18:15:47 发布