【leetcode】二叉树刷题记录
文章目录
前言
本文是基于leetcode二叉树例题的学习记录
LCR 145. 判断对称二叉树
自己写的代码
class Solution {
public:
bool checkSymmetricTree(TreeNode* root) {
if(!root)return true;
return isSymmetricTree(root->left, root->right);
}
bool isSymmetricTree(TreeNode* A, TreeNode* B)
{
if(!A)return (bool)!B;
if(!B)return (bool)!A;
if(A && B && A->val != B->val)return false;
return A && B && isSymmetricTree(A->left, B->right) && isSymmetricTree(A->right, B->left);
}
};
题解代码
思路:构造一个辅助函数判断两棵树是否是镜像对称的,然后题目只要判断两棵这个树是否镜像对称
而比较两棵树是否镜像对称,即一棵树的左子树和另一棵树的右子树,以及一棵树的右子树和另一棵树的左子树是否镜像对称
特殊判断:都是空树满足条件;其中有一棵空树不满足条件
作者:星晴pro
链接:https://leetcode.cn/problems/shu-de-zi-jie-gou-lcof/solutions/791039/yi-pian-wen-zhang-dai-ni-chi-tou-dui-che-uhgs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
bool isSymmetric(TreeNode*root)
{
return isMirror(root, root);
}
bool isMirror(TreeNode*p, TreeNode*q)
{
if (!p && !q)
return true;
if (!p || !q)
return false;
return (p->val == q->val) && (isMirror(p->left, q->right)) && (isMirror(p->right, q->left));
}
如果直接从两个根节点开始递归代码会更简洁
104. 二叉树的最大深度
自己写的
没啥好说的
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root)return 0;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
100. 相同的树
自己写的
也没啥好说的~
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p && !q)return true;
if(p && q && p->val != q->val)return false;
return p && q && isSameTree(p -> left, q -> left) && isSameTree(p -> right, q -> right);
}
};
110. 平衡二叉树
自己写的
跟求最大深度联系上了
class Solution {
public:
bool isBalanced(TreeNode* root) {
if(!root)return true;
return abs(maxDepth(root->left) - maxDepth(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right);
}
int maxDepth(TreeNode* root)
{
if(!root)return 0;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
另一种写法 后序遍历 + 剪枝 (从底至顶)
效率更高
思路是对二叉树做后序遍历,从底至顶返回子树深度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。
算法流程:
函数 recur(root) :
返回值:
当节点root 左 / 右子树的深度差 ≤1 :则返回当前子树的深度,即节点 root 的左 / 右子树的深度最大值 +1 ( max(left, right) + 1 )。
当节点root 左 / 右子树的深度差 >1 :则返回 −1 ,代表 此子树不是平衡树 。
终止条件:
当 root 为空:说明越过叶节点,因此返回高度 0 。
当左(右)子树深度为 −1 :代表此树的 左(右)子树 不是平衡树,因此剪枝,直接返回 −1 。
函数 isBalanced(root) :
返回值: 若 recur(root) != -1 ,则说明此树平衡,返回 true ; 否则返回 false 。
作者:Krahets
链接:https://leetcode.cn/problems/balanced-binary-tree/solutions/8737/balanced-binary-tree-di-gui-fang-fa-by-jin40789108/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
bool isBalanced(TreeNode* root) {
return recur(root) != -1;
}
private:
int recur(TreeNode* root) {
if (root == nullptr) return 0;
int left = recur(root->left);
if (left == -1) return -1;
int right = recur(root->right);
if (right == -1) return -1;
return abs(left - right) < 2 ? max(left, right) + 1 : -1;
}
};
965. 单值二叉树
自己写的
class Solution {
public:
bool isUnivalTree(TreeNode* root) {
if(!root)return true;
if(root->left)
{
if(root->val != root->left->val) return false;
if(!isUnivalTree(root->left)) return false;
}
if(root->right)
{
if(root->val != root->right->val) return false;
if(!isUnivalTree(root->right)) return false;
}
return true;
}
};
572. 另一棵树的子树
自己写的
class Solution {
public:
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
if(!subRoot)return true;
if(!root)return false;
if(root && subRoot && root->val == subRoot->val)return isSametree(root, subRoot) || isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
bool isSametree(TreeNode* p, TreeNode* q) {
if(!p && !q)return true;
if(p && q && p->val != q->val)return false;
return p && q && isSametree(p -> left, q -> left) && isSametree(p -> right, q -> right);
}
};
写得挺糟糕的,原来只写了if(root && subRoot && root->val == subRoot->val)return isSametree(root, subRoot);会报错,忽视了像[1,1],[1]这种用例,只能在原来的代码上改了
题解代码
判断一个数是不是另一颗树的子树
特殊判断:有一颗树为空就不成立
这道题的思路比较特殊,先判断两棵树是否是相同,如果相同那么就是满足题意的,
然后判断一棵树的左子树是否是另一颗树的子树/一棵树的右子树是否是另一颗树的子树
作者:星晴pro
链接:https://leetcode.cn/problems/shu-de-zi-jie-gou-lcof/solutions/791039/yi-pian-wen-zhang-dai-ni-chi-tou-dui-che-uhgs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
bool isSubtree(TreeNode*root1, TreeNode*root2)
{
if (!root1 || !root2)
return false;
if (isSameTree(root1, root2))
return true;
return isSubtree(root1->left, root2) || isSubtree(root1->right, root2);
}
226. 翻转二叉树
自己写的
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(!root)return nullptr;
invertTree(root->left);
invertTree(root->right);
swap(root->left, root->right);
return root;
}
};
先交换再递归好像要快一些,给swap换个位置
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(!root)return nullptr;
swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
617. 合并二叉树
自己写的
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if (root1 && root2)
{
root1->val += root2->val;
root1->left = mergeTrees(root1->left, root2->left);
root1->right = mergeTrees(root1->right, root2->right);
}
return root1 ? root1 : root2;
}
};
LCR 143. 子结构判断
自己写的
上面那些题做过一遍之后来看这道还是没那么难的
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
return (A != nullptr && B != nullptr) && (recur(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B));
}
bool recur(TreeNode* A, TreeNode* B) {
if(B == nullptr) return true;
if(A == nullptr || A->val != B->val) return false;
return recur(A->left, B->left) && recur(A->right, B->right);
}
};