leetcode-对称二叉树

检查一个二叉树是否是镜像的
1.递归实现
毫无疑问,递归的实现比较容易,从根节点的左右孩子开始,先判断根的特殊情况,再进入递归,判断是在回溯的时候判断。
官方解法是把2个root当作第一次左右传入,这个想法很好,代码也好看

 bool isSymmetric(TreeNode* root) {
        if(root == nullptr){
            return true;
        }
        if(root->left == nullptr && root->right == nullptr){
            return true;
        }
        else if(root->left != nullptr && root->right != nullptr){
                return is(root->left,root->right);
        }
            return false;
    }
    //
    bool is(TreeNode *l,TreeNode *r){
        if(l == nullptr && r == nullptr){
            return true;
        }
        //这句是可以去掉的
        /*if(l == nullptr || r == nullptr){
            return false;
        }*/
        /*if(l != nullptr && r != nullptr &&  l->val == r->val){
          return is(l->left,r->right) && is(l->right,r->left);
        }*/
        return l != nullptr && r != nullptr &&  l->val == r->val &&is(l->left,r->right) && is(l->right,r->left);
         //return false;       
}

2.非递归
非递归想到了栈,大概思路是用2个栈分别存入当前节点的左右,然后循环
2.1 2个栈,遇到的难题主要是在判断时,没有把情况考虑清楚,什么时候该continue,什么时候直接false,总是报错nullptr

  //2个栈实现
  bool isSymmetric(TreeNode* root) {
    if(root == nullptr)
            return true;
            //判断根节点得左右孩子是否满足
    if((root->left != nullptr && root->right == nullptr) || (root->left == nullptr && root->right != nullptr)){
                return false;
        }
        //当左右孩子都存在
    if(root->left != nullptr && root->right != nullptr){
        stack<TreeNode*>s1;
        stack<TreeNode*>s2;
        //左右入栈,主要是为了第一次进while,应该可以优化
        s1.push(root->left);
        s2.push(root->right);
        while(!s1.empty() && !s2.empty()){
            TreeNode* l = s1.top();
            TreeNode* r = s2.top();
            //出栈
            s1.pop();
            s2.pop();
            //判断节点值是否相等
            if(l == nullptr && r == nullptr) continue;
            if(l == nullptr || r == nullptr) return false;
            if(l->val != r->val){
                return false;
            }
            //放在这里会出错,不知道为什么
            /*s1.pop();
            s2.pop();*/
            //这个问题困扰我很久,当当前节点的孩子与对应节点的孩子不满足情况(一个为空,一个不为空,一共四种情况),直接返回false
                s2.push(r->left); 
                s2.push(r->right);
                s1.push(l->right);
                s1.push(l->left);
            }
            //如果最后,都出栈了,说明ok
            
        } 
                 return true;       
    }

2.2 1个栈
一个栈实现,代码实现更容易,主要是没想到这个思路,思路很重要

bool isSymmetric(TreeNode* root) {
        if(root == nullptr)
            return true;
        stack<TreeNode*>s1;
        s1.push(root->left);
        s1.push(root->right);
        while(!s1.empty()){
            TreeNode*l = s1.top();
            s1.pop();
            TreeNode*r = s1.top();
            s1.pop();
            if(r == nullptr && l == nullptr){
                continue;
            }
            if(r == nullptr || l == nullptr){
                return false;
            }
            if(l->val != r->val)
            return false;
            s1.push(r->left);
            s1.push(l->right);
            s1.push(r->right);
            s1.push(l->left); 
        }
        return true;
    }

总结一下,非递归用其他容器也可以,总体思路差不多。
总的思路就是前中后序的非递归的基础,这个题做了挺久,还是三序的代码不熟练,思路理的不太清楚

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值