《剑指offer》82--二叉树中和为某一值的路径(一)[C++][Java]

一、题目描述

描述

给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。

1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点

2.叶子节点是指没有子节点的节点

3.路径只能从父节点到子节点,不能从子节点到父节点

4.总节点数目为n


例如:
给出如下的二叉树,sum=22,
 


返回true,因为存在一条路径 5→4→11→2的节点值之和为 22

数据范围:

1.树上的节点数满足 0≤n≤10000

2.每 个节点的值都满足 ∣val∣≤1000

要求:空间复杂度 O(n),时间复杂度 O(n)

进阶:空间复杂度 O(树的高度),时间复杂度 O(n)

示例1

输入:{5,4,8,1,11,#,9,#,#,2,7},22

返回值:true

示例2

输入:{1,2},0

返回值:false

示例3

输入:{1,2},3

返回值:true

示例4

输入:{},0

返回值:false

二、解题思路

1. 递归(建议)

  • 时间复杂度:O(n),其中n为二叉树所有节点,前序遍历二叉树所有节点
  • 空间复杂度:O(n),最坏情况二叉树化为链表,递归栈空间最大为n

【C++】

class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if (root == nullptr) return false;
        if (root->left == nullptr && root->right == nullptr && sum == root->val) return true;
        int res = sum - root->val;
        return hasPathSum(root->left, res) || hasPathSum(root->right, res);
    }
};

【Java】

import java.util.*;

public class Solution {
    public boolean hasPathSum (TreeNode root, int sum) {
        if (root == null) return false;
        if (root.left == null && root.right == null && sum == root.val) return true;
        int res = sum - root.val;
        return hasPathSum(root.left, res) || hasPathSum(root.right, res);
    }
}

2. dfs

  • 时间复杂度:O(n),其中n为二叉树所有节点,遍历二叉树所有节点
  • 空间复杂度:O(n),最坏情况二叉树化为链表,递归栈空间最大为n

【C++】

class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(root == nullptr) return false; //空节点找不到路径
        stack<pair<TreeNode*, int> > s; //栈辅助深度优先遍历,并记录到相应节点的路径和
        s.push({root, root->val}); //根节点入栈
        while(!s.empty()){
            auto temp = s.top();
            s.pop();
            if(temp.first->left == nullptr && temp.first->right == nullptr
                && temp.second == sum) {
                return true;
            }
            if(temp.first->left != nullptr) { //左节点入栈
                s.push({temp.first->left, temp.second + temp.first->left->val}); 
            }
            if(temp.first->right != nullptr) { //右节点入栈 
                s.push({temp.first->right, temp.second + temp.first->right->val});
            }
        }
        return false;
    }
};

【Java】

import java.util.*;

public class Solution {
    public boolean hasPathSum (TreeNode root, int sum) {
        if (root == null) return false;
        Stack<TreeNode> s1 = new Stack<TreeNode>();
        Stack<Integer> s2 = new Stack<Integer>();
        s1.push(root);
        s2.push(root.val);
        while (!s1.isEmpty()) {
            TreeNode temp = s1.pop();
            int cur_sum = s2.pop();
            if (temp.left == null && temp.right == null && cur_sum == sum) return true;
            if (temp.left != null) {
                s1.push(temp.left);
                s2.push(cur_sum + temp.left.val);
            }
            if (temp.right != null) {
                s1.push(temp.right);
                s2.push(cur_sum + temp.right.val);
            }
        }
        return false;
    }
}

三、相关题目

《剑指offer》55--二叉树的深度 | 平衡二叉树[C++]

《剑指offer》79--判断是不是平衡二叉树[C++][Java]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贫道绝缘子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值