【leetcode】二叉树刷题记录

【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);
    }
};
  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值