《录鼎记》第十五章——二叉树part04

今日内容:

  • 110.平衡二叉树
  • 257. 二叉树的所有路径
  • 404.左叶子之和

一、平衡二叉树

力扣题目链接 (opens new window)

本体因为要求是否符合平衡二叉树,平衡二叉树要求高度差不能大于1,所以应用后序遍历的递归。

然后上递归三部曲:

1、确定返回值和函数参数:

由于返回的是二叉树的高度差,所以返回值应为int型数据。递归参数应为树节点。

int getheight(Treenode* node)

2、明确终止条件

当以所遇节点为根节点的树高度为0时说明遇到了空节点,应返回。

if(node ==NULL){
    return 0;
}

3、单层逻辑

左子树遍历的值为-1,则整个不符合,右子树遍历值为-1,则整个也不符合。

然后在比较该节点是否二者差的绝对值大于一,若大于1则不符合。

若不大于1则返回最大高度+1;

int leftHeight = getHeight(node->left);
if (leftHeight == -1) return -1;
int rightHeight = getHeight(node->right);
if (rightHeight == -1) return -1;
return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftHeight, rightHeight)

读完代码后才感受到这题用后序遍历的必要性,能先推到子树然后逐级返回。

有了递归三部曲之后感觉就顺水推舟,但是自己还是没有太好的思路。

class Solution {
public:
   int getheight(TreeNode* node){
       if(node==NULL) return 0;
       int leftheight = getheight(node->left);
       if(leftheight==-1) return -1;
       int rightheight = getheight(node->right);
       if(rightheight==-1) return -1;
       return abs(leftheight-rightheight) >1 ? -1:1+max(leftheight,rightheight);


   }
    bool isBalanced(TreeNode* root) {
        return getheight(root)==-1? false:true;


    }
};

迭代大致看懂等2刷了。

2、 二叉树的所有路径

力扣题目链接 (opens new window)

这题因为要输出所有的路径,所以需要从叶子节点回溯到前面的节点。

下面就要用递归三部曲。

1、确定参数及返回值

本体输出的时路径不需要返回值,所以类型是void,要输出路径所以参数为节点,路径,和result

void traversal(TreeNode* cur, vector<int>& path, vector<string>& result)

2、找到终止条件

要找叶子节点,所以左右子树都要指向空。

if (cur->left == NULL && cur->right == NULL) { // 遇到叶子节点
    string sPath;
    for (int i = 0; i < path.size() - 1; i++) { // 将path里记录的路径转为string格式
        sPath += to_string(path[i]);
        sPath += "->";
    }
    sPath += to_string(path[path.size() - 1]); // 记录最后一个节点(叶子节点)
    result.push_back(sPath); // 收集一个路径
    return;
}

3、单层递归

if (cur->left) {
    traversal(cur->left, path, result);
    path.pop_back(); // 回溯
}
if (cur->right) {
    traversal(cur->right, path, result);
    path.pop_back(); // 回溯
}

4、整体

class Solution {
public:
   void traversal(TreeNode* cur,vector<int>& path,vector<string>& result){
       path.push_back(cur->val);
       if(cur->left==NULL&&cur->right==NULL){
           string sPath;
           for(int i=0;i<path.size()-1;i++){
               sPath+=to_string(path[i]);
               sPath+="->";
           }
           sPath +=to_string(path[path.size()-1]);
           result.push_back(sPath);
           return;
       }
       if(cur->left){
           traversal(cur->left,path,result);
           path.pop_back();

       }
       if(cur->right){
           traversal(cur->right,path,result);
           path.pop_back();
       }
   }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result;
        vector<int> path;
        if(root==NULL) return result;
        traversal(root,path,result);
        return result;

    }
};

整体有待进一步理解。

三、做叶子之和

力扣题目链接 (opens new window)

本来想用层级遍历试试,但确实没法确认是不是左孩子.

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        queue<TreeNode*> que;
        if(root==NULL) return 0;
        int num=0;
        que.push(root);
        while(!que.empty()){
            int size= que.size();
            for(int i=0;i<size;i++){
                TreeNode* node = que.front();
                que.pop();
                if(node->left!=NULL&&node->left->left==NULL&&node->left->right==NULL){
                    num+=node->left->val;
                }
                if(node->right) que.push(node->right);
                if(node->left) que.push(node->left);
            }
            

            
        }
        return num;

    }
};

后来看题解恍然大悟。

回溯法:

递归三部曲:1、确定递归函数的参数和返回值

返回数值之和所以为int

2、确定终止条件

if(root==NULL) return 0;

3、确定单层递归的逻辑

int leftValue = sumOfLeftLeaves(root->left);    // 左
if (root->left && !root->left->left && !root->left->right) {
    leftValue = root->left->val;
}
int rightValue = sumOfLeftLeaves(root->right);  // 右

int sum = leftValue + rightValue;               // 中
return sum;

整体:

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(root==NULL) return 0;
        if(root->left==NULL&&root->right==NULL) return 0;
        int leftValue =sumOfLeftLeaves(root->left);
        if(root->left&&!root->left->left&&!root->left->right){
            leftValue=root->left->val;
        }
        int rightValue =sumOfLeftLeaves(root->right);
        int sum=leftValue+rightValue;
        return sum;

    }
};

整体难度比较大,花的时间也挺长,理解程度不够。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值