剑指 Offer 26. 树的子结构
题目
剑指 Offer 26. 树的子结构 难度:medium
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
示例 1:
输入: A = [1,2,3], B = [3,1]
输出: false
示例 2:
输入: A = [3,4,5,1,2], B = [4,1]
输出: true
限制:
0 <= 节点个数 <= 10000
方法一:先序遍历
思路
若树 B 是树 A 的子结构,则子结构的根节点可能为树 A 的任意一个节点。因此,判断树 B 是否是树 A 的子结构,需完成以下两步工作:
- 先序遍历树 A 中的每个节点 $n_A$;(对应函数
isSubStructure(A, B)
) - 判断树 A 中 以 $n_A$ 为根节点的子树 是否包含树 B 。(对应函数
recur(A, B)
)
recur(A, B)
函数:
1. 终止条件:
1. 当节点 B 为空:说明树 B 已匹配完成(越过叶子节点),因此返回 true ;
2. 当节点 A 为空:说明已经越过树 A 叶子节点,即匹配失败,返回 false ;
3. 当节点 A 和 B 的值不同:说明匹配失败,返回 false ;
2. 返回值:
1. 判断 A 和 B 的左子节点是否相等,即 recur(A.left, B.left) ;
2. 判断 A 和 B 的右子节点是否相等,即 recur(A.right, B.right) ;
isSubStructure(A, B)
函数:
- 特例处理: 当 树 A 为空 或 树 B 为空 时,直接返回 false ;
返回值: 若树 B 是树 A 的子结构,则必满足以下三种情况之一,因此用或
||
连接:- 以 节点 A 为根节点的子树 包含树 B ,对应
recur(A, B)
; - 树 B 是 树 A 左子树 的子结构,对应
isSubStructure(A.left, B)
; - 树 B 是 树 A 右子树 的子结构,对应
isSubStructure(A.right, B)
;
- 以 节点 A 为根节点的子树 包含树 B ,对应
解题
Python:
class Solution:
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
def recur(A, B):
if not B: return True
if not A or A.val != B.val: return False
return recur(A.left, B.left) and recur(A.right, B.right)
return bool(A and B) and (recur(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B))
Java:
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
return (A != null && B != null) && (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));
}
boolean recur(TreeNode A, TreeNode B) {
if(B == null) return true;
if(A == null || A.val != B.val) return false;
return recur(A.left, B.left) && recur(A.right, B.right);
}
}
剑指 Offer 27. 二叉树的镜像
题目
剑指 Offer 27. 二叉树的镜像 难度:easy
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
例如输入:
4
/ \
2 7
/ \ / \
1 3 6 9
镜像输出:
4
/ \
7 2
/ \ / \
9 6 3 1
示例 1:
输入: root = [4,2,7,1,3,6,9]
输出: [4,7,2,9,6,3,1]
限制:
0 <= 节点个数 <= 1000
方法一:递归
思路
这是一道很经典的二叉树问题。显然,我们从根节点开始,递归地对树进行遍历,并从叶子节点先开始翻转得到镜像。如果当前遍历到的节点 $\textit{root}$ 的左右两棵子树都已经翻转得到镜像,那么我们只需要交换两棵子树的位置,即可得到以 $\textit{root}$ 为根节点的整棵子树的镜像。
解题
Python:
class Solution:
def mirrorTree(self, root: TreeNode) -> TreeNode:
if not root:
return root
left = self.mirrorTree(root.left)
right = self.mirrorTree(root.right)
root.left, root.right = right, left
return root
Java:
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if (root == null) {
return null;
}
TreeNode left = mirrorTree(root.left);
TreeNode right = mirrorTree(root.right);
root.left = right;
root.right = left;
return root;
}
}
后记
📝 上篇精讲: 【算法题解】 Day22 搜索与回溯
💖 我是 𝓼𝓲𝓭𝓲𝓸𝓽,期待你的关注;
👍 创作不易,请多多支持;
🔥 系列专栏: 算法题解