对称二叉树

https://leetcode.cn/problems/symmetric-tree/

思路:

详细的解释可以参考卡哥的代码随想录(https://programmercarl.com/0101.%E5%AF%B9%E7%A7%B0%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E9%80%92%E5%BD%92%E6%B3%95),写的非常详细,本文仅作为个人学习后针对自己思路的整理。

首先我们看到这道题目,想到如何去做?我们学习了三种遍历方法,递归迭代(栈)层序(队列),任何题目无非是在这三大类中去找寻思路,我们再去审题。

判断左右对称并不是左节点右节点,而是根节点的左右子树,节点的左右判断完后,要判断根节点的左右的子节点,详细的说也就是根节点的左节点的左节点(示例中的3)对比根节点的右节点的右节点(示例中的3),在对比根节点的右节点的左节点和根节点左节点的右节点(4),这个时候我们发现,我们想要判断每一层的这几个节点是否相等,但凡有不相等的就return false。这下就有思路了。

首先是递归,依然是确认递归三要素:

  1. 参数和返回值:题目要求返回true or false,所以我们使用bool,参数的话我们分别讨论左子树和右子树。

 bool compareTree(TreeNode* left, TreeNode* right){

2 .终止条件:只有都为空的时候会停下,其余情况可以看上面的例子分析。

 if(left != NULL && right == NULL) return false;
        else if(left == NULL && right != NULL) return false;
        else if(left == NULL && right == NULL) return true;
        else if(left != NULL && right != NULL && left -> val != right -> val) return false;

3.单层递归逻辑:

此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。

  • 比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。

  • 比较内测是否对称,传入左节点的右孩子,右节点的左孩子。

  • 如果左右都对称就返回true ,有一侧不对称就返回false 。

bool outside = compare(left->left, right->right);   // 左子树:左、 右子树:右
bool inside = compare(left->right, right->left);    // 左子树:右、 右子树:左
bool isSame = outside && inside;                    // 左子树:中、 右子树:中(逻辑处理)
return isSame;

整体代码如下:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if (root == NULL) return true;
        return compareTree(root->left, root->right);


    }
    bool compareTree(TreeNode* left, TreeNode* right){
        if(left != NULL && right == NULL) return false;
        else if(left == NULL && right != NULL) return false;
        else if(left == NULL && right == NULL) return true;
        else if(left != NULL && right != NULL && left -> val != right -> val) return false;
        bool outside = compareTree(left -> left,right -> right);
        bool inside = compareTree(left -> right,right -> left);
        bool issame = outside && inside;
        return issame;
    }
};

同样的思路可以使用迭代法:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if (root == NULL) return true;
        queue<TreeNode*> que;
        que.push(root->left);   // 将左子树头结点加入队列
        que.push(root->right);  // 将右子树头结点加入队列
        
        while (!que.empty()) {  // 接下来就要判断这两个树是否相互翻转
            TreeNode* leftNode = que.front(); que.pop();
            TreeNode* rightNode = que.front(); que.pop();
            if (!leftNode && !rightNode) {  // 左节点为空、右节点为空,此时说明是对称的
                continue;
            }

            // 左右一个节点不为空,或者都不为空但数值不相同,返回false
            if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
                return false;
            }
            que.push(leftNode->left);   // 加入左节点左孩子
            que.push(rightNode->right); // 加入右节点右孩子
            que.push(leftNode->right);  // 加入左节点右孩子
            que.push(rightNode->left);  // 加入右节点左孩子
        }
        return true;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值