二叉树OJ题(1)

目录

1.相同的树

2.对称二叉树

3.翻转二叉树

4.另一颗树的子树


  • 题目代码
  • 思路整体分析&注意事项
  • 易错点
  • 画图递归分析

    树=根+左子树+右子树

  • 分支的思想

  • 多情况考虑

1.相同的树

100. 相同的树 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/same-tree/description/

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if(p == NULL && q == NULL)
    {
        return true;
    }
    if(p == NULL || q == NULL)
    {
        return false;
    }
    //两个都不为NULL
    if(p->val == q->val)
    {
        return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
    }
    return false;
}
  • 分治思想:根和根比较相同----->左子树和左子树比较&&右子树和右子树比较 
  • 一个节点一个节点比较(每个节点看成自己的根)
  • 两棵树的根节点都是NULL
  • 两棵树的一个根节点为NULL,另外一个不为NULL
  • 两棵树根节点都不为NULL
  1. 两个节点中数字相等,则继续往下比较(遍历比较)
  2. 不相等则返回false

    易错点

  • && 必须左右两边子树都相等都为true才可返回true

2.对称二叉树

101. 对称二叉树 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/symmetric-tree/

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    //都为null
    if(p == NULL && q == NULL)
    {
        return true;
    }
    //一个为为null 
    if(p == NULL || q == NULL)
    {
        return false;
    }
    //两个都不为空
    if(p->val == q->val)
    {
      return isSameTree(p->left,q->right) && isSameTree(p->right,q->left);
    }
    return false;
}


bool isSymmetric(struct TreeNode* root) {

    return isSameTree(root->left,root->right);
}
  • 分支思想:把左子树和右子树看成两棵树比较
  • 调用isSameTree
  • isSameTree是左节点等于右节点,右节点等于左节点,形成镜像相等
  • 其他同isSameTree

3.翻转二叉树

LCR 144. 翻转二叉树 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/er-cha-shu-de-jing-xiang-lcof/description/

//方法1--交换向下
struct TreeNode* mirrorTree(struct TreeNode* root){
    if(root == NULL)
    {
        return NULL;
    }
    struct TreeNode*tmp=root->left;
    root->left=root->right;
    root->right=tmp;
    mirrorTree(root->left);
    mirrorTree(root->right);
    return root;
}
  • 方法1:交换往下,返回根节点
  • 分治思想:根指向的左右子树交换
  • 空树返回空
  • 交换左右子树
  • 往下走
  • 交换完左右子树,返回根节点

//方法2--向下交换
struct TreeNode* mirrorTree(struct TreeNode* root){
    if(root == NULL){
        return NULL;
    }
    struct TreeNode *left = mirrorTree(root -> left);
    struct TreeNode *right = mirrorTree(root -> right);
    root -> left = right;
    root -> right = left;
    return root;
}
  • 方法2:向下交换。向下 / 返回根节点 / 保存根节点 / 然后交换 
  • 分支思想:根指向的左右子树交换
  • 向下
  • 返回根节点 / 空
  • 保存根节点 / 空
  • 节点和节点交换 (空和空交换)

  • 易错点
  • 返回值一定需要接收吗?
  • ?结构体交换 ?只交换val 
  • 递归返回:return / 程序结束

4.另一颗树的子树

572. 另一棵树的子树 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/subtree-of-another-tree/description/

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    //都为null
    if(p == NULL && q == NULL)
    {
        return true;
    }
    //一个为为null 
    if(p == NULL || q == NULL)
    {
        return false;
    }
    //两个都不为空
    if(p->val == q->val)
    {
      return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
    }
    return false;
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(root == NULL)
    {
        return false;
    }
    if(root->val == subRoot->val)
    {                                                                           
        if(isSameTree(root,subRoot))//返回true
        {
            return true;
        } 
    }
    return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}
  • 分治思想:左右子树遍历+比较
  • 若为空树 则返回false
  • 若不为空树,遍历root
  • 比较并且找到第一个与subRoot子树的根节点相等的节点
  • 从这个节点开始比较后面的节点root&subRoot
  • 比较遍历整个子树subRoot

    易错点

  • || 左右子树有一个包含subRoot即可
  • 从第一个相等的节点开始遍历比较
  1. 若全部相等,则root返回true
  2. 若不相等,不能root返回false,存在第二个相等的节点(还可能遍历) 

5.平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode)

🙂感谢大家的阅读,若有错误和不足,欢迎指正

  • 30
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐唐思

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值