94. 二叉树的中序遍历
# 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 Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
left = self.inorderTraversal(root.left)
right = self.inorderTraversal(root.right)
return left + [root.val] + right
104.二叉树的最大深度
# 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 Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
return 1+max(self.maxDepth(root.left), self.maxDepth(root.right))
226.翻转二叉树
# 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 Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return
root.left, root.right = root.right, root.left
self.invertTree(root.left)
self.invertTree(root.right)
return root
101.对称二叉树
【递归法】
class Solution:
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
102.二叉树的层序遍历
双端队列: collections.deque()
从开端弹出元素 popleft() ;从尾端弹出元素 , pop()
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
res = []
if root == None: return []
deque = collections.deque([root])
while deque:
level = []
for _ in range(len(deque)):
node = deque.popleft()
level.append(node.val)
if node.left:
deque.append(node.left)
if node.right:
deque.append(node.right)
res.append(level)
return res
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
res = []
self.helper(root, 0, res)
return res
def helper(self, node, level, res):
if not node:
return
if len(res) == level: #先按层数,把【】里面套的【】全都建好
res.append([])
res[level].append(node.val)
self.helper(node.left, level + 1, res) #指定框子
self.helper(node.right, level + 1, res)
108.将有序数组转换为二叉搜索树
class Solution:
def traversal(self, nums: List[int], left: int, right: int) -> TreeNode:
if left > right:
return None
mid = left + (right - left) // 2
root = TreeNode(nums[mid])
root.left = self.traversal(nums, left, mid - 1)
root.right = self.traversal(nums, mid + 1, right)
return root
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
root = self.traversal(nums, 0, len(nums) - 1)
return root
98.验证二叉搜索树【!】
中序遍历
利用pre和cur双指针
class Solution:
def __init__(self):
self.pre = None # 用来记录前一个节点
def isValidBST(self, root):
if root is None:
return True
left = self.isValidBST(root.left)
if self.pre is not None and self.pre.val >= root.val:
return False
self.pre = root # 记录前一个节点
right = self.isValidBST(root.right)
return left and right
递归法(版本一)利用中序递增性质,转换成数组
class Solution:
def __init__(self):
self.vec = []
def traversal(self, root):
if root is None:
return
self.traversal(root.left)
self.vec.append(root.val) # 将二叉搜索树转换为有序数组
self.traversal(root.right)
def isValidBST(self, root):
self.vec = [] # 清空数组
self.traversal(root)
for i in range(1, len(self.vec)):
# 注意要小于等于,搜索树里不能有相同元素
if self.vec[i] <= self.vec[i - 1]:
return False
return True
230.二叉搜索树中第K小的元素
递归法(版本一)利用中序递增性质,转换成一个递增数组
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
self.vec = []
self.travel(root)
return self.vec[k-1]
def travel(self, root):
if not root:
return None
self.travel(root.left)
self.vec.append(root.val)
self.travel(root.right)
199.二叉树的右视图
== 层序遍历==
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
res = []
if not root :
return res
queue = collections.deque([root])
while queue:
level_length = len(queue) #给一个迭代前的长度,不要放在迭代里面,要不然会更新改变
for _ in range(len(queue)): #这个len(queue) 不会更新
node = queue.popleft()
if _ == level_length-1:
res.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return res
114.二叉树展开为链表【后序遍历】
后序遍历
class Solution:
def flatten(self, root: Optional[TreeNode]) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root:
return
self.flatten(root.left) ##左子树变成一长条
self.flatten(root.right) ##右子树变成一长条
#### root.right=左子树,右子树接到左节点的末尾 ####
left = root.left
right = root.right
root.left = None
root.right = left
cur = root #cur一定是赋值给root,而不是root.left,如果root.left为空,会报错
while cur.right:
cur = cur.right
cur.right = right
105.从前序与中序遍历序列构造二叉树【前序】
前序遍历
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: #中左右, 左中右
if len(preorder) == 0 :
return None
root_val = preorder[0]
root = TreeNode(val = root_val) #建立头节点
split_index = inorder.index(root_val) #找到分割点
root.left = self.buildTree(preorder[1:split_index+1], inorder[:split_index])
root.right = self.buildTree(preorder[split_index+1:], inorder[split_index+1:])
return root
437.路径总和3【较难】
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:
if not root:
return 0
left_cnt = self.pathSum(root.left, targetSum)
right_cnt = self.pathSum(root.right, targetSum)
#路径总和 = root开始的路径数 + 左子树路径总和 + 右子树路径总和
return self.rootsum(root, targetSum)+ left_cnt+ right_cnt
def rootsum(self, root,targetSum)-> int: #计算root到某个节点的和等于targetsum的路径数目
if not root:
return 0
ans = 0
if root.val == targetSum: #找到路径
ans += 1
left = self.rootsum(root.right, targetSum-root.val)
right = self.rootsum(root.left, targetSum-root.val)
return ans + left + right #当前位置的结果+往左走+往右走
236.二叉树的最近公共祖先【后序遍历】
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root == p or root == q: return root
if root == None: return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right,p,q)
#左右有一个空,则返回另一个不空的,如果都空,则返回None;都不空,返回root
if left != None and right == None:
return left
elif left == None and right != None:
return right
elif left != None and right != None:
return root
else :
return None
543.二叉树的直径【全局变量】
二叉树的直径,因为他不一定经过root,但是,最长路径,一定是有个公共祖先,所以,只要有个全局变量self.max记录就行
# 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 Solution:
def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
self.maxwid = 0
self.findwid(root)
return self.maxwid
def findwid(self, root) -> int: #给一个节点,计算过这个node的树的直径 left+right
if not root:
return 0
left = self.findwid(root.left) #左子树的高度
right = self.findwid(root.right)
self.maxwid = max(self.maxwid, left + right ) #更新最大直径
return max(left, right) + 1
124.二叉树中最大的路径和【全局变量】
class Solution:
def maxPathSum(self, root: Optional[TreeNode]) -> int:
self.maxlen = -float('inf')
if not root:
return self.maxlen
self.dfs(root)
return self.maxlen
def dfs(self, root): #返回从根节点到节点的最大路径和【路径至少包含一个节点】
if not root:
return 0
left = max(self.dfs(root.left),0)
right = max(self.dfs(root.right),0)
self.maxlen = max(self.maxlen, left + right + root.val)
return root.val + max(left, right)