代码随想录刷题随记15-二叉树回溯

代码随想录刷题随记15-二叉树回溯

110.平衡二叉树

leetcode链接
一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
求深度和求高度的区别:
求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)
递归:
所以这里的递归其实是后序遍历的思路

class Solution {
public:
    void subjudge(bool & isbalanced,int&height ,TreeNode * root){
        if(root==nullptr){
            isbalanced=true;
            height=0;
            return;
        }    
        int heightleft,heightright;
        bool ifleftb,ifrightb;       
        subjudge(ifleftb, heightleft, root->left);
        subjudge(ifrightb, heightright, root->right);
        if((ifleftb &&ifrightb)&&(abs(heightleft-heightright)<=1))
          isbalanced=true;
        else
          isbalanced=false;
        height=heightleft>heightright?heightleft+1:heightright+1;
    }
    bool isBalanced(TreeNode* root) {
        bool isbalanced;
        int height;
         subjudge(isbalanced,height,root);
        return isbalanced;
    }
};

此题用迭代法,其实效率很低,因为没有很好的模拟回溯的过程,所以迭代法有很多重复的计算。虽然理论上所有的递归都可以用迭代来实现,但是有的场景难度可能比较大。

例如:都知道回溯法其实就是递归,但是很少人用迭代的方式去实现回溯算法!

257. 二叉树的所有路径

leetcode链接

class Solution {
public:
   void sub(TreeNode* root,vector<int>&path,vector<string>& ret){
     if(root!=nullptr)
        path.push_back(root->val);
     if(root->left==nullptr&&root->right==nullptr){
        string tmp="";
        for(int i=0;i<path.size()-1;i++){
            tmp+=to_string(path[i]);
            tmp += "->";
        }
         tmp+=to_string(path[path.size()-1]);
        ret.push_back(tmp);
        return;
     }
     if(root->left!=nullptr){
        sub(root->left,path,ret);
        path.pop_back();//回溯

     }
     if(root->right!=nullptr){
        sub(root->right,path,ret);
        path.pop_back();//回溯
     }
     return;
   }
    vector<string> binaryTreePaths(TreeNode* root) {
       vector<string> ret;
       vector<int> path;
       if(root==nullptr)
       return {};
       sub(root,path,ret);
       return ret;
    }
};

迭代版本

404.左叶子之和

leetcode链接

class Solution {
public:
    vector<string> binaryTreePaths(TreeNode* root) {
       vector<string> ret;
       stack<string> stackPath;
       stack<TreeNode*> stackNode;
       if(root==nullptr)
       return {};
       stackNode.push(root);
       stackPath.push("");
       while(!stackNode.empty()){
           TreeNode * cur=stackNode.top();
           stackNode.pop();
           string path=stackPath.top();
           stackPath.pop();            
           path+=to_string(cur->val); 
           path+="->";
           if(cur->left==nullptr&&cur->right==nullptr){
            path.pop_back();
            path.pop_back();
            ret.push_back(path);
           }
           if(cur->left!=nullptr){
             stackNode.push(cur->left);
             stackPath.push(path);
           }
           if(cur->right!=nullptr){
             stackNode.push(cur->right);
             stackPath.push(path);
           }         
       }
       return ret;
    }
};

404.左叶子之和

leetcode链接
当前节点没法判断自己是不是左叶子,必须要通过节点的父节点来判断其左孩子是不是左叶子。
判断代码如下:

if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
    左叶子节点处理逻辑
}
class Solution {
public:
   void sub(TreeNode * root,int& sum){
      if(root==nullptr)
        return;
    if(root->right!=nullptr){
            sub(root->right,sum);
    }
    if(root->left!=nullptr&&root->left->left==nullptr&&root->left->right==nullptr){
        sum+=root->left->val;
        return;
    }
    if(root->left!=nullptr){
       sub(root->left,sum);
    }  
    }
    int sumOfLeftLeaves(TreeNode* root) {
        int sum=0;
        sub(root,sum);
        return sum;
    }
};

迭代法
本题迭代法使用前中后序都是可以的,只要把左叶子节点统计出来,就可以了

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        int sum=0;
         stack<TreeNode*>mystack;
         if(root==nullptr)
         return 0;
         mystack.push(root);
         while(!mystack.empty()){
            TreeNode * cur=mystack.top();
            mystack.pop();
            if(cur->right!=nullptr){
               mystack.push(cur->right);
            }
             if(cur->left!=nullptr&&cur->left->left==nullptr&&cur->left->right==nullptr){
                sum+=cur->left->val;
                continue;
             }
             if(cur->left!=nullptr){
               mystack.push(cur->left);
            }
         }
         
        return sum;
    }
};
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值