代码随想录DAY18:二叉树

二叉树

513. 找树左下角的值

513. 找树左下角的值

题目描述

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

思路

层序遍历,遍历每一层,最左侧数值更新 res。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    //迭代法:队列
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL)   que.push(root);
        int res;
        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;
    }
};

112. 路径总和

112. 路径总和

题目描述

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

思路

递归 & 回溯
1、参数与返回值
参数:节点、表示路径总和的 int 型变量
返回值:bool类型,true or false

2、终止条件
(1)到达叶子节点且满足路径总和 --> true
(2)到达叶子节点但不满足路径总和 --> false

3、单层的操作
路径:已经走过的节点之和
选择列表:非空左子树、非空右子树
注意:下一层返回上层时,(path 相关的)count 需要回溯

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool traverse(TreeNode* node, int count)
    {
        //触发终止条件
        if (!node->left && !node->right && count == 0)      return true;
        if (!node->left && !node->right)    return false;

        //左右子树
        if (node->left)
        {
            count -= node->left->val;
            if(traverse(node->left, count))    return true;
            count += node->left->val;
        }

        if (node->right)
        {
            count -= node->right->val;
            if(traverse(node->right, count))    return true;
            count += node->right->val;
        }

        return false;
    }

    //回溯
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == NULL)   return false;
        return traverse(root, targetSum - root->val);
    }
};

113. 路径总和 II

113. 路径总和 II

题目描述

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

思路

递归 & 回溯
1、参数与返回值
参数:节点、表示路径总和的 int 型变量
返回值:void类型,需要遍历整个二叉树

2、终止条件
(1)到达叶子节点且满足路径总和,path 对 res 更新;
(2)到达叶子节点但不满足路径总和,只 return;

3、单层的操作
路径:已经走过的节点之和、已经走过的节点的记录
选择列表:非空左子树、非空右子树
注意:下一层返回上层时,count 需要回溯、记录路径的 path 也要回溯

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    void traverse(TreeNode* node, int count)
    {
        //触发结束条件
        if (!node->left && !node->right && count == 0)
        {
            res.push_back(path);
            return;
        }

        if (!node->left && !node->right)    return;

        if (node->left)
        {
            path.push_back(node->left->val);
            count -= node->left->val;
            traverse(node->left,count);
            count += node->left->val;
            path.pop_back();
        }

        if (node->right)
        {
            path.push_back(node->right->val);
            count -= node->right->val;
            traverse(node->right, count);
            count += node->right->val;
            path.pop_back();
        }

        return;
    }

    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        res.clear();
        path.clear();
        if (root == NULL)   return res; 
        //if (root != NULL)
        path.push_back(root->val);
        traverse(root, targetSum - root->val);
        return res;
    }
};

105. 从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树

题目描述

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

思路

由先序确定根节点,在中序找到相应位置,划分左右子树,递归构造左右子树,完成二叉树的构造。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    //<key,value> key:数值 value:下标
    unordered_map<int,int> valToIndex;

    TreeNode* build(vector<int>& preorder, int preStart, int preEnd, vector<int>& inorder, int inStart, int inEnd)
    {
        if (preStart > preEnd)
            return NULL;
        //从前序确定 “根节点”
        int rootVal = preorder[preStart];
        //找到 “根节点” 在中序的下标,以划分左右子树
        int index = valToIndex[rootVal];
        int leftSize = index - inStart;
        //树的构造:根节点
        TreeNode* root = new TreeNode(rootVal);
        //树的构造:左子树
        root->left = build(preorder, preStart+1, preStart+leftSize, inorder, inStart, index-1);
        //树的构造:右子树
        root->right = build(preorder,preStart+leftSize+1,preEnd,inorder,index+1,inEnd);
        return root;
    }

    
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for(int i = 0; i < inorder.size(); i++)
        {
            valToIndex[inorder[i]] = i;
        }
        return build(preorder, 0, preorder.size()-1, inorder, 0, inorder.size()-1);
    }
};

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

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

题目描述

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

思路

由后序确定根节点,在中序找到相应位置,划分左右子树,递归构造左右子树,完成二叉树的构造。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    //<key, value> key:元素值 value:下标
    unordered_map<int,int> valToIndex;

    TreeNode* build(vector<int>& inorder, int inStart, int inEnd, vector<int>& postorder, int postStart, int postEnd)
    {
        if (postStart > postEnd)
        {
            return nullptr;
        }
        //根据后序确定 “根节点”
        int rootVal = postorder[postEnd];
        //找到 “根节点” 在中序的下标
        int index = valToIndex[rootVal];
        //划定左子树范围,含有几个节点
        int leftSize = index - inStart;
        //树的构造:根节点
        TreeNode* root = new TreeNode(rootVal);
        //树的构造:左子树
        root->left = build(inorder, inStart, index - 1, postorder, postStart, postStart + leftSize - 1);
        //树的构造:右子树
        root->right = build(inorder, index + 1, inEnd, postorder, postStart + leftSize, postEnd - 1);
        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        for(int i = 0; i < postorder.size(); i++)
        {
            valToIndex[inorder[i]]=i;
        }
        return build(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值