代码随想录day18

513.找树左下角的值

给定一个二叉树,在树的最后一行找到最左边的值。

        1.递归法

      采用先序遍历 ,每次更新最大高度时,就记录result。

int maxDepth = INT_MIN;
int result;
void traversal(TreeNode* root, int depth) {
    if (root->left == NULL && root->right == NULL) {
        if (depth > maxDepth) {
            maxDepth = depth;
            result = root->val;
        }
        return;
    }
    if (root->left) {
        traversal(root->left, depth + 1); // 隐藏着回溯
    }
    if (root->right) {
        traversal(root->right, depth + 1); // 隐藏着回溯
    }
    return;
}
int findBottomLeftValue(struct TreeNode* root) {
    int ans=travel(root,1);
    return ans;
}
        2.迭代法

        采用层序遍历,每次新到达一层时,就记录第一个元素的值。 

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        int ans=root->val;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()){
            int n=que.size();
            for(int i=0;i<n;++i){
                TreeNode* cur=que.front();
                que.pop();
                //记录一层开头第一个节点
                if(i==0) ans=cur->val;
                if(cur->left) que.push(cur->left);
                if(cur->right) que.push(cur->right);
            }
        }
        return ans;
    }
};

112. 路径总和 

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例: 给定如下二叉树,以及目标和 sum = 22,返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

           递归法 
bool travel(struct TreeNode* root, int sum){
    //当sum为0时,返回true
    if(root->left==NULL&&root->right==NULL&&sum==0) return true;
    if(root->left==NULL&&root->right==NULL) return false;
    if(root->left){
        sum-=root->left->val;
        if(travel(root->left,sum)) return true;
        sum+=root->left->val;//回溯
    }
    if(root->right){
        sum-=root->right->val;
        if(travel(root->right,sum)) return true;
        sum+=root->right->val;//回溯
    }
    return false;
}
bool hasPathSum(struct TreeNode* root, int targetSum) {
    if(root==NULL) return false;
    return travel(root,targetSum-root->val);
}

  113.路径总和II

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

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

        要遍历整个树,找到所有路径,所以递归函数不要返回值 

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    void dfs(TreeNode *root,int targetSum){
        if(root==nullptr){
            return;
        }
        //保存中间路径
        path.emplace_back(root->val);
        targetSum-=root->val;
        if(root->left==nullptr&&root->right==nullptr&&targetSum==0){
            ans.emplace_back(path);
        }
        dfs(root->left,targetSum);
        dfs(root->right,targetSum);
        //搜完后删除当前路径
        path.pop_back();
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        dfs(root,targetSum);
        return ans;
    }
};

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

 根据一棵树的中序遍历与后序遍历构造二叉树。

注意: 你可以假设树中没有重复的元素。

例如,给出

        中序遍历 inorder = [9,3,15,20,7]

        后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树:

class Solution {
private:
    TreeNode* traversal (vector<int>& inorder, vector<int>& 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 InIndex;
        for(InIndex=0;InIndex<inorder.size();InIndex++) {
            if(inorder[InIndex] == rootValue) break;
        }

        // 切割中序数组
        // 左闭右开区间:[0, delimiterIndex)
        vector<int> leftInorder(inorder.begin(),inorder.begin()+ InIndex);
        // [delimiterIndex + 1, end)
        vector<int> rightInorder(inorder.begin()+InIndex+1, inorder.end());

        // postorder 舍弃末尾元素
        postorder.resize(postorder.size() - 1);

        // 切割后序数组
        // 依然左闭右开,注意这里使用了左中序数组大小作为切割点
        // [0, leftInorder.size)
        vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
        // [leftInorder.size(), end)
        vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());

        root->left = traversal(leftInorder, leftPostorder);
        root->right = traversal(rightInorder, rightPostorder);

        return root;
    }
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size() == 0 || postorder.size() == 0) return NULL;
        return traversal(inorder, postorder);
    }
};

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值