(补)打卡第十八天|力扣513.找树左下角的值、112. 路径总和 、106.从中序与后序遍历序列构造二叉树

今天是第十八天,二叉树进入到比较难的部分了,需要更好地理解递归和回溯

513. 找树左下角的值

这道题的话用层序遍历会很容易,就遍历到最后一层然后最左边的值就行

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

当然,用递归也可以做,只是复杂一些

每一步的递归和回溯都要想清楚

class Solution {
public:
//int类型的最小值
    int maxDepth = INT_MIN;
    int result;
    void find(TreeNode*root, int depth){
        if(root->left == NULL && root->right == NULL){
//更新最大深度
            if(depth > maxDepth){
                maxDepth = depth;
//保存数值
                result = root->val;
            }
        }
        if(root->left){
            depth++;
         find(root->left,depth);
//--是回溯的步骤
            depth--;
        }
        if(root->right){
            depth++;
            find(root->right,depth);
            depth--;
        }
    }
    int findBottomLeftValue(TreeNode* root) {
    
    find(root, 0);
    return result;
    
    }
};

112. 路径总和

递归三部曲

  1. 类型:我们函数定义成bool类型,因为我们不需要返回深度什么之类的,传入参数就是当前节点和目标数值

  1. 终止条件:到达叶结点停止,也就是左右节点都为空的时候

  1. 单层逻辑:依次往下遍历,记得回溯即可

这里代码比较复杂,不够简洁,但可以更好地体现出回溯的过程

class Solution {
public:
    bool traversal(TreeNode* cur, int count){
        if(!cur->left && !cur->right && count == 0)return true;
        if(!cur->left && !cur->right)return false;

        if(cur->left){
//又+又-就是回溯的过程
            count -= cur->left->val;
            if(traversal(cur->left, count))return true;
            count += cur->left->val;
        }
        if(cur->right){
            count -=cur->right->val;
            if(traversal(cur->right, count))return true;
            count += cur->right->val;
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
         if(root == NULL)return 0;
         return traversal(root, targetSum - root->val);
    }
};

106. 从中序与后序遍历序列构造二叉树

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

TreeNode* traversal (vector& inorder, vector& postorder) {

    // 第一步
    if (postorder.size() == 0) return NULL;

    // 第二步:后序遍历数组最后一个元素,就是当前的中间节点
    int rootValue = postorder[postorder.size() - 1];
    TreeNode* root = new TreeNode(rootValue);

    // 叶子节点
    if (postorder.size() == 1) return root;

    // 第三步:找切割点
    int delimiterIndex;
    for (delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++) {
        if (inorder[delimiterIndex] == rootValue) break;
    }

    // 第四步:切割中序数组,得到 中序左数组和中序右数组
    // 第五步:切割后序数组,得到 后序左数组和后序右数组

    // 第六步
    root->left = traversal(中序左数组, 后序左数组);
    root->right = traversal(中序右数组, 后序右数组);

    return root;
}

你可能感兴趣的:(刷题日记,算法,数据结构,leetcode,c++)