吾日三省吾身
还记得的梦想吗
正在努力实现它吗
可以坚持下去吗
目录
[力扣题号:101. 对称二叉树 - 力扣(LeetCode)](#力扣题号:101. 对称二叉树 - 力扣(LeetCode))
|---------|-------|
| (。♥‿♥。) | (◕‿◕) |
| (◠‿◠) | (^▽^) |
| (◔◡◔) | (◉‿◉) |
然后接下来是学英语环节
|--------------|----------------|
| decline | 下降,衰退,减少 |
| reject | 拒绝 |
| refusal | 拒绝 |
| desert | n. 沙漠,冷清的地方 |
| desert | v. 遗弃,丢弃 |
| discard | 扔掉,丢弃(一样具体的东西) |
| abandon | 抛弃,放弃 |
| acquaint | v. 使了解,使认识 |
| acquaintance | n. 认识,了解 |
| deserve | 应得,应受(奖励、惩罚) |
力扣题号:101. 对称二叉树 - 力扣(LeetCode)
注:下述题目描述和示例均来自力扣
题目描述
给你一个二叉树的根节点 root
, 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
提示:
- 树中节点数目在范围
[1, 1000]
内 -100 <= Node.val <= 100
思路
解法:递归调用
大体思路
-
特殊情况处理: 如果根节点为空,直接返回true;如果根节点的左右子树都为空,也返回true。
-
递归比较: 通过递归地比较左右子树的节点,判断它们是否对称。在递归比较时,每次比较左子树的左节点和右子树的右节点,以及左子树的右节点和右子树的左节点。
-
比较结果返回: 如果左右子树都为空,返回true;如果左右子树中有一个为空,返回false;如果左右子树的节点值不相等,返回false;否则,继续递归比较左右子树的节点,直到完成对整棵树的对称比较。
代码逻辑解释
详细的代码解释在代码中有极其详细的注解
- 在递归比较左右子树时,采用的是类似后序遍历的方式,确保能够从底层节点逐层向上返回比较结果。
- 在比较每个节点时,先比较左子树的左节点和右子树的右节点,然后比较左子树的右节点和右子树的左节点。
注意事项
- 特殊情况的处理能够简化代码逻辑,提高效率。
- 通过递归比较左右子树的节点,实现了对整棵树的对称性判断。
- 对于对称二叉树的判断,需要同时考虑左右子树的对称性,因此采用了递归的方式进行比较。
代码实现
Java
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left, root.right);
}
public boolean compare(TreeNode left, TreeNode right){
// 进来之后先判断是否有空值的情况
// 如果左空,右不空,返回false
// 如果左不空,右空,返回false
// 如果左空,右空,返回ture
if (left == null && right != null){
return false;
}else if (left != null && right == null){
return false;
}else if (left == null && right == null){
return true;
}
// 如果左右都不空,但是值不一样返回false
if (left.val != right.val){
return false;
}
// 好小子,没有BUG,那么我只能说牛,继续递归吧
// 这里递归需要的是后续遍历,这样才能往上返回结果
// 但是同时也需要注意的是,因为是要对称的比较,
// 所以左子树上的遍历顺序是 左 右 中 这个没有问题
// 但是 右子树上的遍历顺序是 右 左 中 虽然不是标准的后续遍历
// 但是代码糙理不糙
// 左 右
boolean out = compare(left.left, right.right);
// 右 左
boolean inside = compare(left.right, right.left);
// 中 中
boolean res = out && inside;
return res;
}
}
又快又小,如果我把后面声明的变量都去掉的话就更。。。。。
java
return compare(root.left, root.right);
}
public boolean compare(TreeNode left, TreeNode right){
// 进来之后先判断是否有空值的情况
// 如果左空,右不空,返回false
// 如果左不空,右空,返回false
// 如果左空,右空,返回ture
if (left == null && right != null){
return false;
}else if (left != null && right == null){
return false;
}else if (left == null && right == null){
return true;
}
// 如果左右都不空,但是值不一样返回false
if (left.val != right.val){
return false;
}
// 好小子,没有BUG,那么我只能说牛,继续递归吧
// 这里递归需要的是后续遍历,这样才能往上返回结果
// compare(left.left, right.right);
// compare(left.right, right.left);
return compare(left.left, right.right) && compare(left.right, right.left);
}
}
这样可以少声明一些变量,使得无需声明更多的内存空间
C++
cpp
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
return compare(root->left, root->right);
}
bool compare(TreeNode* left, TreeNode* right) {
if (!left && !right) {
return true;
} else if (!left || !right) {
return false;
}
if (left->val != right->val) {
return false;
}
return compare(left->left, right->right) && compare(left->right, right->left);
}
};
我运行了好几次才跑出来0ms,太玄学了。。。。。。。。。。
总结
我从不总结谢谢ヾ( ̄▽ ̄)Bye~Bye~
这里主要就是要判断关键点就是对于空位置的true,false判断和递归的遍历方式的抉择,如果拿捏了这两个关键点的话,就拿捏了这道题了。