一、树的子结构
剑指 Offer 26. 树的子结构https://leetcode.cn/problems/shu-de-zi-jie-gou-lcof/
输入两棵二叉树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
解题思路:
1.判断树B是否是树A的子结构要遍历树A的每个节点An;
2.判断树A中以An为根节点的子树是否包含树B。
具体细节:
1.用match(A,B)函数来进行匹配,当B为空时,说明匹配完成返回true;
2.当A为空时,说明没有匹配完全,或者AB节点值不同时返回false;
3.递归返回A和B的左右子节点是否相等:match(A->left,B->left) && match(A->right,B->right);
4.用isSubStructure(A,B)函数来遍历树A的每个节点,当A或B为空时直接返回false;
5.返回以A为根节点是否与B匹配或者以A的左右子树是否与B匹配:match(A,B) || isSubStructure(A->left,B) || isSubStructure(A->right,B)。
复杂度分析:
1.时间复杂度: O(N^2)。
2.空间复杂度:O(1)。
代码实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (A == NULL || B == NULL) return false;
return match(A, B) || isSubStructure(A -> left, B) || isSubStructure(A -> right, B);
}
bool match(TreeNode* A, TreeNode* B) {
if (B == NULL) return true;
if (A == NULL || A -> val != B -> val) return false;
return match(A -> left, B -> left) && match(A -> right, B -> right);
}
};
二、二叉树的镜像
剑指 Offer 27. 二叉树的镜像https://leetcode.cn/problems/er-cha-shu-de-jing-xiang-lcof/
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
例如输入:
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
解题思路:
1.递归遍历树将左右子树交换。
具体细节:
1.当根节点为空时直接返回空;
2.将左右子树交换;
3.递归将左右子树左为根节点交换左右子树。
复杂度分析:
1.时间复杂度:O(N)。
2.空间复杂度:O(1)。
代码实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if (root == NULL) return NULL;
TreeNode* temp = root -> left;
root -> left = root -> right;
root -> right = temp;
root -> left = mirrorTree(root -> left);
root -> right = mirrorTree(root -> right);
return root;
}
};
三、判断二叉树是否对称
剑指 Offer 28. 对称的二叉树https://leetcode.cn/problems/dui-cheng-de-er-cha-shu-lcof/
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
限制:
0 <= 节点个数 <= 1000
解题思路:
1.遍历树的每个节点,判断以此节点为根节点的二叉树是否为对称二叉树,如果都是则此树也是。
2.叶子节点为对称二叉树。
具体细节:
1.实现match(A,B)判断左右子树是否对称。
2.当AB都为空时返回true;
3.当A为空或B为空或AB值不同时返回false;
4.返回A的左子树和B的右子树是否对称以及A的右子树和B的左子树是否对称:match(A->left,B->right)&&match(A->right,B->left)。
复杂度分析:
1.时间复杂度:O(N)。
2.空间复杂度:O(1)。
代码实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if (root == NULL) return true;
return match(root -> left, root -> right);
}
bool match(TreeNode* A, TreeNode* B) {
if (A == NULL && B == NULL) return true;
if (A == NULL || B == NULL || A -> val != B -> val) return false;
return match(A -> left, B -> right) && match(A -> right, B -> left);
}
};