8.完全二叉树的节点个数
class TreeNode:
def __init__(self,val):
self.val = val
self.left = None
self.right = None
import collections
#普通二叉树递归法
class Solution:
def countNodes(self,root:TreeNode):
if not root:
return 0
return 1 + self.countNodes(root.left) + self.countNodes(root.right)
#普通二叉树迭代法:
class Solution:
def countNodes(self,root:TreeNode):
queue =collections.deque()
if root:
queue.append(root)
res = 0
while queue:
size = len(queue)
for i in range(size):
node = queue.popleft()
res += 1
if node.left:queue.append(node.left)
if node.right:queue.append(node.right)
return res
#满二叉树:
class Solution:
def countNodes(self,root:TreeNode):
if not root:
return 0
left = root.left
right = root.right
leftH = 0
rightH = 0
while left:
left = left.left
leftH += 1
while right:
right = right.right
rightH += 1
if leftH == rightH:
return (2 << leftH) - 1
return self.countNodes(root.left) + self.countNodes(root.right) + 1
9.平衡二叉树
class Solution:
def isBalanced(self,root:TreeNode):
return self.recur(root) != -1
def recur(self,root):
if not root:return 0
left = self.recur(root.left)
if left == -1:return -1
right = self.recur(root.right)
if right == -1:return -1
return max(left + right) + 1 if abs(left - right) < 2 else -1
10.二叉树的所有路径
import collections
#深度优先搜索
class Solution:
def binaryTreePaths(self, root: TreeNode):
def construct_paths(root, path):
if root:
path += str(root.val)
if not root.left and not root.right:
paths.append(path)
else:
path += '->'
construct_paths(root.left, path)
construct_paths(root.right, path)
paths = []
construct_paths(root, '')
return paths
#广度优先搜索
class Solution:
def binaryTreePaths(self, root: TreeNode):
paths = list()
if not root:
return paths
node_queue = collections.deque([root])
path_queue = collections.deque(str(root.val))
while node_queue:
node = node_queue.popleft()
path = path_queue.popleft()
if not node.left and not node.right:
paths.append(path)
else:
if node.left:
node_queue.append(node.left)
path_queue.append(path + '->' + str(node.left.val))
if node.right:
node_queue.append(node.right)
path_queue.append(path + '->' + str(node.right.val))
return paths
11.相同的树
class Solution:
def isSameTree(self,p:TreeNode,q:TreeNode):
return self.compare(p,q)
def compare(self,tree1,tree2):
if not tree1 and tree2:
return False
elif tree1 and not tree2:
return False
elif not tree1 and not tree2:
return True
elif tree1.val != tree2.val:
return False
compareLeft = self.compare(tree1.left,tree2.left)
compareRight = self.compare(tree1.right,tree2.right)
isSame = compareLeft and compareLeft
return isSame
12.左叶子之和
#递归后序
class Solution:
def sumOfLeftLeaves(self,root:TreeNode):
if not root:
return 0
l_l_lea_sum = self.sumOfLeftLeaves(root.left)
r_l_lea_sum = self.sumOfLeftLeaves(root.right)
cur_left_lea_val = 0
if root.left and not root.left.left and not root.left.right:
cur_left_lea_val = root.left.val
return cur_left_lea_val + l_l_lea_sum + r_l_lea_sum
#迭代
class Solution:
def sumOfLeftLeaves(self, root: TreeNode):
stack = []
if root:
stack.append(root)
res = 0
while stack:
cur_node = stack.pop()
if cur_node.left and not cur_node.left.left and not cur_node.left.right:
res += cur_node.left.val
if cur_node.left:
stack.append(cur_node.left)
if cur_node.right:
stack.append(cur_node.right)
return res
13.找树左下角的值
import collections
class Solution:
def findBottomLeftValue(self,root:TreeNode):
queue = collections.deque()
if root:
queue.append(root)
res = 0
while queue:
node = queue.popleft()
if node.right:#先右
queue.append(node.right)
if node.left:#后左
queue.append(node.left)
return node.val
14..从前序与中序遍历序列构造二叉树、从中序与后序遍历序列构造二叉树
#从前序与中序遍历序列构造二叉树
class Solution:
def buildTree(self,preorder,inorder):
# 第一步: 特殊情况讨论: 树为空. 或者说是递归终止条件
if not preorder:
return None
# 第二步: 前序遍历的第一个就是当前的中间节点.
root_val = preorder[0]
root = TreeNode(root_val)
# 第三步: 找切割点.
sepa_idx = inorder.index(root_val)
# 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
inorder_left = inorder[:sepa_idx]
inorder_right = inorder[sepa_idx + 1:]
# 第五步: 切割preorder数组. 得到preorder数组的左,右半边.
# ⭐️ 重点1: 中序数组大小一定跟前序数组大小是相同的.
preorder_left = preorder[1:1 + len(inorder_left)]
preorder_right = preorder[1 + len(inorder_right):]
# 第六步: 递归
root.left = self.buildTree(preorder_left,inorder_left)
root.right = self.buildTree(preorder_right,inorder_right)
return root
#从中序与后序遍历序列构造二叉树
class Solution:
def buildTree(self,inorder,postorder):
# 第一步: 特殊情况讨论: 树为空. (递归终止条件)
if not postorder:
return None
# 第二步: 后序遍历的最后一个就是当前的中间节点.
root_val = postorder[-1]
root = TreeNode(root_val)
# 第三步: 找切割点.
sep_idx = inorder.index(root_val)
# 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
inorder_left = inorder[:sep_idx]
inorder_right = inorder[sep_idx + 1:]
# 第五步: 切割postorder数组. 得到postorder数组的左,右半边.
# ⭐️ 重点1: 中序数组大小一定跟后序数组大小是相同的.
postorder_left = postorder[: len(inorder_left)]
postorder_right = postorder[len(inorder_left): len(inorder) - 1]
# 第六步: 递归
root.left = self.buildTree(inorder_left,postorder_left)
root.right = self.buildTree(inorder_right,postorder_right)
return root
15.最大二叉树
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
- 二叉树的根是数组中的最大元素。
- 左子树是通过数组中最大值左边部分构造出的最大二叉树。
- 右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
class Solution:
def buildTree(self,nums):
if not nums:
return None
root_val = max(nums)
root = TreeNode(root_val)
idx = nums.index(root_val)
nums_left = nums[:idx]
nums_right = nums[idx + 1:]
root.left = self.buildTree(nums_left)
root.right = self.buildTree(nums_right)
return root
16.合并二叉树
import collections
#递归
class Solution:
def mergeTrees(self,root1,root2):
# 递归终止条件:
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
if not root1:
return root2
if not root2:
return root1
root1.val += root2.val
root1.left = self.mergeTrees(root1.left,root2.left)
root1.right = self.mergeTrees(root1.right,root2.right)
return root1
#迭代
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
if not root1:
return root2
if not root2:
return root1
queue = collections.deque()
queue.append(root1)
queue.append(root2)
while queue:
node1 = queue.popleft()
node2 = queue.popleft()
# 更新queue
# 只有两个节点都有左节点时, 再往queue里面放.
if node1.left and node2.left:
queue.append(node1.left)
queue.append(node2.left)
# 只有两个节点都有右节点时, 再往queue里面放.
if node1.right and node2.right:
queue.append(node1.right)
queue.append(node2.right)
# 更新当前节点. 同时改变当前节点的左右孩子.
node1.val += node2.val
if not node1.left and node2.left:
node1.left = node2.left
if not node1.right and node2.right:
node1.right = node2.right
return root1
17.路径总和①
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
#递归
class Solution:
def haspathsum(self, root: TreeNode, targetsum: int) -> bool:
def recur(root,tar):
if not root.left and not root.right and tar == 0:# 遇到叶子节点,并且计数为0
return True
if not root.left and not root.right:# 遇到叶子节点,计数不为0
return False
if root.left:
tar -= root.left.val# 左节点
if recur(root.left,tar):return True# 递归,处理左节点
tar += root.left.val # 回溯
if root.right:
tar -= root.right.val # 右节点
if recur(root.right, tar): return True # 递归,处理右节点
tar += root.right.val # 回溯
return False
if not root:
return False
else:
return recur(root,targetsum - root.val)
#迭代 - 层序遍历
class solution:
def haspathsum(self, root: TreeNode, targetsum: int) -> bool:
if not root:
return False
stack = [] # [(当前节点,路径数值), ...]
stack.append((root, root.val))
while stack:
cur_node, path_sum = stack.pop()
if not cur_node.left and not cur_node.right and path_sum == targetsum:
return True
if cur_node.right:
stack.append((cur_node.right, path_sum + cur_node.right.val))
if cur_node.left:
stack.append((cur_node.left, path_sum + cur_node.left.val))
return False
18.路径总和②
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
class solution:
def pathsum(self, root: TreeNode, targetsum: int):
def recur(root,tar):
if not root.left and not root.right and tar == 0:
res.append(path[:])
return
if not root.left and not root.right:return
if root.left:
path.append(root.left.val)
tar -= root.left.val
recur(root.left,tar)
path.pop()
tar += root.left.val
if root.right:
path.append(root.right.val)
tar -= root.right.val
recur(root.right, tar)
path.pop()
tar += root.right.val
res = []
path = []
if not root:
return []
path.append(root.val)
recur(root,targetsum - root.val)
return res
19.二叉搜索树中的搜索
给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。
#递归法
class Solution:
def searchBST(self, root: TreeNode, val: int):
if not root:
return None
if root.val == val:
return root
if root.val > val:
return self.searchBST(root.left,val)
if root.val < val:
return self.searchBST(root.right, val)
#迭代法
class Solution:
def searchBST(self, root: TreeNode, val: int):
while root:
if val == root.val:
return root
root = root.left if val < root.val else root.right
return None