【Leetcode二叉树属性一】101. 对称二叉树 100.相同的树 572. 另一棵树的子树

Leetcode101

1.问题描述

在这里插入图片描述

2.解决方案

解法一:递归比较内侧外侧

在这里插入图片描述

class Solution3{
public:
    bool compare(TreeNode* left,TreeNode* right){
        if(left!= nullptr&&right== nullptr) return false;
        if(left== nullptr&&right!= nullptr) return false;
        if(left== nullptr&&right== nullptr) return true;
        if(left!= nullptr&&right!= nullptr&&left->val!=right->val) return false;

        //进入这说明是left!= nullptr&&right!= nullptr&&left->val==right->val的情况
        bool outside= compare(left->left,right->right);
        bool inside= compare(left->right,right->left);
        return outside&&inside;
    }
    bool isSymmetric(TreeNode* root) {
        if(root== nullptr) return true;
        else return compare(root->left,root->right);
    }
};


解法二:迭代法一对结点一对的比较

这个迭代法是使用队列类似于层序遍历,但是我一开始使用了两个队列分别存贮,这就导致了判断起来十分复杂,有多种特殊情况非常难实现,然后如果使用一个队列一次出队两个节点,这样就好判断了许多

在这里插入图片描述

正确代码
class Solution2 {
public:
    bool check(TreeNode* left, TreeNode* right) {
        queue <TreeNode*> q;
        q.push(left); q.push(right);

        //选择一个队列进行比较而不是像上面的两个队列进行比较
        while (!q.empty()) {
            left = q.front(); q.pop();
            right= q.front(); q.pop();

            //比较的过程
            //1.都空continue
            if (!left && !right) continue;
            //2.一个空一个不空 或者 两个不空但不相等 false
            if ((!left || !right) || (left->val != right->val)) return false;

            q.push(left->left);
            q.push(right->right);

            q.push(left->right);
            q.push(right->left);
        }
        return true;
    }
    bool isSymmetric(TreeNode* root) {
        if(root== nullptr) return true;
        else return check(root->left,root->right);
    }
};
错误代码
//迭代做法(错误)
class Solution {
public:

    bool IsSamePoint(TreeNode* a,TreeNode* b){
        if(a== nullptr&&b== nullptr) return true;
        if(a!= nullptr&&b!= nullptr&&a->val==b->val) return true;
        return false;
    }
    bool isSymmetric(TreeNode* root) {
        if(root== nullptr) return true;
        if(root!= nullptr&&root->left== nullptr&&root->right== nullptr) return true;

        //q1层序入队顺序先左儿子后右儿子 q2入队顺序先右儿子后左儿子
        queue<TreeNode*> q1;
        queue<TreeNode*> q2;
        q1.push(root);
        q2.push(root);

        while(q1.empty()== false&&q2.empty()== false){
            TreeNode* t1=q1.front();
            TreeNode* t2=q2.front();
            q1.pop();
            q2.pop();
            if(IsSamePoint(t1,t2)== false) return false;

            if(t1== nullptr&&t2== nullptr) continue;
            if(t1->left== nullptr&&t1->right== nullptr) continue;
            if(t2->left== nullptr&&t2->right== nullptr) continue;
            q1.push(t1->left);
            q1.push(t1->right);
            q2.push(t2->right);
            q2.push(t2->left);
        }
        return true;

    }
};



Leetcode100

题目及解答方案

1.题目描述

在这里插入图片描述

2.解决方案

解法一:递归

和101的思路几乎一样的

在这里插入图片描述

//正确递归解法
class Solution1 {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        //先检查
        if(p== nullptr&&q== nullptr) return true;
        if(p!= nullptr&&q== nullptr) return false;
        if(p== nullptr&&q!= nullptr) return false;


        //当前结点相同以及左右子树相同
        return (p->val==q->val)&&isSameTree(p->right,q->right)&&isSameTree(p->left,q->left);
    }
};


解法二:迭代

迭代法就和101的迭代一样,就是使用队列或者栈,一对节点一对节点的进行比较,代码这里就不给出了



Leetcode572

1.问题描述

在这里插入图片描述
在这里插入图片描述

2.解决方案

思路呢,很简单就是前序遍历root树,对每一个结点都和subRoot进行判断是否为同一棵树,至于判断同一棵树的功能就是上一题100的,一模一样,所以问题就是前序遍历root树的细节
1.首先下次回来复习的时候我希望我能再认真分析一次这个递归过程,就是if(递归调用= =true) return true,这个逻辑是怎么传回原函数等等
2.这个遍历逻辑一开始大意了写成了if(isSame(root->left,subRoot) = = true) return true,当时是错的,这样相当于只判断了一次没有递归判断
3.后来又出现了一个问题那就是如果root= =nullpter,if(isSame(root,subRoot)== true) return true,那么如果在第一层判断中没有return true,那么自然就会进入后面的逻辑isSubtree(root->left,subRoot),那么问题来了root->left就段错误了,所以加了一个root!=nullptr,就AC了但是没分析的很清楚这个root和subRoot的空与不空的关系

class Solution {
public:
    bool isSame(TreeNode* p,TreeNode* q){
        //1.
        if(p!= nullptr&&q== nullptr) return false;
        if(p== nullptr&&q!= nullptr) return false;
        if(p== nullptr&&q== nullptr) return true;
        if(p!= nullptr&&q!= nullptr&&p->val!=q->val) return false;

        //2.if(p!= nullptr&&q!= nullptr&&p->val==q->val)
        return isSame(p->left,q->left)&& isSame(p->right,q->right);

    }
    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        if(isSame(root,subRoot)== true) return true;

        //if(isSame(root->left,subRoot)== true) return true;
        //if(isSame(root->right,subRoot)== true) return true;
        if(root!= nullptr&&isSubtree(root->left,subRoot)== true) return true;
        if(root!= nullptr&&isSubtree(root->right,subRoot)== true) return true;

        return false;
    }
};
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值