二叉树专题练习

朱小落

关注

阅读 50

2022-01-27

目录

一.递归遍历

(1)中序遍历

(2)前序遍历

(3)后序遍历

2.迭代法

(1)前序遍历

(2)后序遍历

(3)中序遍历

三.层序遍历

四.226. 翻转二叉树 - 力扣(LeetCode) (leetcode-cn.com)

五.101. 对称二叉树 - 力扣(LeetCode) (leetcode-cn.com)

1.前序遍历

2.迭代法

六.104. 二叉树的最大深度 - 力扣(LeetCode) (leetcode-cn.com)

七.111. 二叉树的最小深度 - 力扣(LeetCode) (leetcode-cn.com)

八.222. 完全二叉树的节点个数 - 力扣(LeetCode) (leetcode-cn.com)

(1)dfs

(2)bfs

(3)完全二叉树的性质

九.110. 平衡二叉树 - 力扣(LeetCode) (leetcode-cn.com)

十.257. 二叉树的所有路径 - 力扣(LeetCode) (leetcode-cn.com)

十一.100. 相同的树 - 力扣(LeetCode) (leetcode-cn.com)

十二.404. 左叶子之和 - 力扣(LeetCode) (leetcode-cn.com)

十三.404. 左叶子之和 - 力扣(LeetCode) (leetcode-cn.com)

十四.513. 找树左下角的值 - 力扣(LeetCode) (leetcode-cn.com)

十五.112. 路径总和 - 力扣(LeetCode) (leetcode-cn.com)

十六.113. 路径总和 II - 力扣(LeetCode) (leetcode-cn.com)

十七.106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)

十八.654. 最大二叉树 - 力扣(LeetCode) (leetcode-cn.com)

十九.617. 合并二叉树 - 力扣(LeetCode) (leetcode-cn.com)


一.递归遍历

(1)中序遍历

无所谓result随不随着函数一起遍历

# 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]:
result=[]
def traversal(root,result):
if root==None:
return
traversal(root.left,result)
result.append(root.val)
traversal(root.right,result)
traversal(root,result)
return result
# 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]:
result=[]
def traversal(root):
if root==None:
return
traversal(root.left)
result.append(root.val)
traversal(root.right)
traversal(root)
return result

(2)前序遍历

# 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 preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result=[]
def traversal(root):
if root==None:
return
result.append(root.val)
traversal(root.left)
traversal(root.right)
traversal(root)
return result

(3)后序遍历

# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result=[]
def traversal(root):
if root==None:
return
traversal(root.left)
traversal(root.right)
result.append(root.val)
traversal(root)
return result

2.迭代法

(1)前序遍历

# 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 preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result=[]
if root==None:
return result
s=[]
s.append(root)
while s:
root=s.pop()
result.append(root.val)
if root.right:s.append(root.right)
if root.left:s.append(root.left)
return result

(2)后序遍历

交换左右节点顺序后翻转

# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result=[]
if not root:
return result
s=[]
s.append(root)
while s:
root=s.pop()
result.append(root.val)
if root.left:s.append(root.left)
if root.right:s.append(root.right)
return result[::-1]

(3)中序遍历

这种思想还是比较难掌握

# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result=[]
if not root:
return []
s=[]
cur=root
while cur or s:
if cur:
s.append(cur)
cur=cur.left
else:
cur=s.pop()
result.append(cur.val)
cur=cur.right
return result

三.层序遍历

# 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 levelOrder(self, root: TreeNode) -> List[List[int]]:
results=[]
if not root:
return results
from collections import deque
que=deque([root])
while que:
size=len(que)
result=[]
for i in range(size):
top=que.popleft()
result.append(top.val)
if top.left:que.append(top.left)
if top.right:que.append(top.right)
results.append(result)
return results

四.226. 翻转二叉树 - 力扣(LeetCode) (leetcode-cn.com)

本质上就是树的先序遍历

只不过每遍历到一个地方,都需要将它的左右节点交换

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

五.101. 对称二叉树 - 力扣(LeetCode) (leetcode-cn.com)

1.前序遍历

本质上仍然是前序遍历

首先判断两节点值是否相等,如果不等,那么肯定不对称

如果相等,那么就分别判断左右孩子

# 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 isSymmetric(self, root: TreeNode) -> bool:
def traversal(r1,r2):
if not r1 and not r2:
return True
if not r1:
return False
if not r2:
return False
if r1.val!=r2.val:
return False
return traversal(r1.left,r2.right) and traversal(r1.right,r2.left)
return traversal(root.left,root.right)

2.迭代法

依然是前序遍历,不过是用栈来实现

# 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 isSymmetric(self, root: TreeNode) -> bool:
stack=[]
stack.append(root.right)
stack.append(root.left)
while stack:
l=stack.pop()
r=stack.pop()
if not l and not r:
continue
if not l:
return False
if not r:
return False
if l.val!=r.val:
return False
stack.append(l.left)
stack.append(r.right)
stack.append(l.right)
stack.append(r.left)
return True

六.104. 二叉树的最大深度 - 力扣(LeetCode) (leetcode-cn.com)

深度优先搜索

# 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
result=0
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
ans=0
def dfs(root,depth):
nonlocal ans
if not root.left and not root.right:
ans=max(ans,depth)
return
if root.left:
dfs(root.left,depth+1)
if root.right:
dfs(root.right,depth+1)
dfs(root,1)
return ans

七.111. 二叉树的最小深度 - 力扣(LeetCode) (leetcode-cn.com)

# 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 minDepth(self, root: TreeNode) -> int:
if not root:
return 0
ans=1<<32
def dfs(root,depth):
nonlocal ans
if not root.left and not root.right:
ans=min(ans,depth)
if root.left:
dfs(root.left,depth+1)
if root.right:
dfs(root.right,depth+1)
dfs(root,1)
return ans

八.222. 完全二叉树的节点个数 - 力扣(LeetCode) (leetcode-cn.com)

(1)dfs

# 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 countNodes(self, root: TreeNode) -> int:
if not root:
return 0
ans=0
def dfs(root):
nonlocal ans
ans+=1
if not root.left and not root.right:
return
if root.left:
dfs(root.left)
if root.right:
dfs(root.right)
dfs(root)
return ans

(2)bfs

# 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 countNodes(self, root: TreeNode) -> int:
result=0
if not root:
return result
from collections import deque
que=deque([root])
while que:
size=len(que)
result+=size
for i in range(size):
top=que.popleft()
if top.left:
que.append(top.left)
if top.right:
que.append(top.right)
return result

(3)完全二叉树的性质

.完全二叉树要么是满二叉树,要么是右下角缺一点点

# 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 countNodes(self, root: TreeNode) -> int:
if not root:
return 0
left=root.left
right=root.right
leftlen=0
rightlen=0
while left:
leftlen+=1
left=left.left
while right:
rightlen+=1
right=right.right
if rightlen==leftlen:
return (2<<rightlen)-1
else:
return 1+self.countNodes(root.left)+self.countNodes(root.right)

九.110. 平衡二叉树 - 力扣(LeetCode) (leetcode-cn.com)

# 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 isBalanced(self, root: TreeNode) -> bool:
if not root:
return True

def getheight(root):
if not root:
return 0
return 1+max(getheight(root.left),getheight(root.right))
return abs(getheight(root.left)-getheight(root.right))<=1 and self.isBalanced(root.left) and self.isBalanced(root.right)
# 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 isBalanced(self, root: TreeNode) -> bool:
def getheight(root):
if not root:
return 0
lefth=getheight(root.left)
righth=getheight(root.right)
if lefth==-1:
return -1
if righth==-1:
return -1
if abs(lefth-righth)>1:
return -1
return 1+max(lefth,righth)
if getheight(root)==-1:
return False
else:
return True

十.257. 二叉树的所有路径 - 力扣(LeetCode) (leetcode-cn.com)

# 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 binaryTreePaths(self, root: TreeNode) -> List[str]:
result=[]
path=[]
if root==None:
return result
self.traversal(root,result,path)
return result

def traversal(self,cur,result,path):
cur.val=str(cur.val)
path.append(cur.val)
if not cur.left and not cur.right:
ans="->".join(path)
result.append(ans)
return
if cur.left:
self.traversal(cur.left,result,path)
path.pop()
if cur.right:
self.traversal(cur.right,result,path)
path.pop()
class Solution:
def binaryTreePaths(self, root: TreeNode) -> List[str]:
result=[]

def dfs(root,path):
nonlocal result
path.append(str(root.val))
if not root.left and not root.right:
result.append("->".join(path))
return
if root.left:
dfs(root.left,path)
if root.right:
dfs(root.right,path)
dfs(root,[])
return result

十一.100. 相同的树 - 力扣(LeetCode) (leetcode-cn.com)

# 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 isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
return True
if not p or not q:
return False
if p.val!=q.val:
return False
return self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)

十二.404. 左叶子之和 - 力扣(LeetCode) (leetcode-cn.com)

# 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 sumOfLeftLeaves(self, root: TreeNode) -> int:
if not root:
return 0
ans=0
def dfs(root):
nonlocal ans
if root.left!=None and root.left.left==None and root.left.right==None:
ans+=root.left.val
if root.left:
dfs(root.left)
if root.right:
dfs(root.right)
return
dfs(root)
return ans

十三.404. 左叶子之和 - 力扣(LeetCode) (leetcode-cn.com)

# 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 sumOfLeftLeaves(self, root: TreeNode) -> int:
if root==None:
return 0
ans=0
s=[]
s.append(root)
while s:
top=s.pop()
if top.left and not top.left.left and not top.left.right:
ans+=top.left.val
if top.left:
s.append(top.left)
if top.right:
s.append(top.right)
return ans

十四.513. 找树左下角的值 - 力扣(LeetCode) (leetcode-cn.com)

# 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 findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
ans=0
maxdepth=-1
def dfs(root,depth):
nonlocal ans
nonlocal maxdepth
if depth>maxdepth:
maxdepth=depth
ans=root.val
if root.left:
dfs(root.left,depth+1)
if root.right:
dfs(root.right,depth+1)
dfs(root,1)
return ans

十五.112. 路径总和 - 力扣(LeetCode) (leetcode-cn.com)

# 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 hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
def dfs(root,sums):
sums+=root.val
if sums==targetSum and not root.left and not root.right:
return True
if not root.left and not root.right:
return False
a=False
b=False
if root.left:a=dfs(root.left,sums)
if root.right:b=dfs(root.right,sums)
return a or b
return dfs(root,0)

十六.113. 路径总和 II - 力扣(LeetCode) (leetcode-cn.com)

# 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 pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
result=[]
if not root:
return result
def dfs(root,path,sums):
nonlocal result
# path.append(root.val)
# sums+=root.val
cursum=sums+root.val
if not root.left and not root.right:
if cursum==targetSum:
result.append(path+[root.val])
return
if root.left:
dfs(root.left,path+[root.val],sums+root.val)
if root.right:
dfs(root.right,path+[root.val],sums+root.val)
dfs(root,[],0)
return result

十七.106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)

# 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 buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
if not inorder:
return None
rootnode=postorder[-1]
root=TreeNode(rootnode)
index=inorder.index(rootnode)

leftin=inorder[:index]
rightin=inorder[index+1:]
leftpost=postorder[:len(leftin)]
rightpost=postorder[len(leftin):-1]

root.left=self.buildTree(leftin,leftpost)
root.right=self.buildTree(rightin,rightpost)
return root

十八.654. 最大二叉树 - 力扣(LeetCode) (leetcode-cn.com)

# 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 constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
if not nums:
return None
rootnode=max(nums)
index=nums.index(rootnode)
root=TreeNode(rootnode)
root.left=self.constructMaximumBinaryTree(nums[:index])
root.right=self.constructMaximumBinaryTree(nums[index+1:])
return root

十九.617. 合并二叉树 - 力扣(LeetCode) (leetcode-cn.com)

# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
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

精彩评论(0)

0 0 举报