作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/path-sum/#/description

题目描述

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

For example:
Given the below binary tree and sum = 22,

          5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1

return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

题目大意

从根节点到叶子节点是否存在一条路径,它的所有节点的和等于target.

解题方法

DFS

这个题要背下来!!

首先是 DFS 解法,该解法的想法是一直向下找到叶子节点,如果到叶子节点sum == 0,说明找到了一条符合要求的路径。

我自己第一遍做的时候犯了一个错误,把递归函数写成了下面的解法:

def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if not root:
return sum == 0
return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)

这种代码的错误在,没有判断 root 是否为叶子节点。比如 root 为空的话,题目的意思是要返回 False 的,而上面的代码会返回 sum == 0。又比如,对于测试用例 树为[1,2], sum = 0 时,上面的结果也会返回为 True,因为对于上述代码,只要左右任意一个孩子的为空时 sum == 0 就返回 True 。

当题目中提到了叶子节点时,正确的做法一定要同时判断节点的左右子树同时为空才是叶子节点。

Python 代码如下:

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if not root: return False
if not root.left and not root.right:
return sum == root.val
return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)

Java 代码如下:

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null){
return false;
}
if(root.left == null && root.right == null){
return root.val == sum;
}
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val); }
}

回溯

这里的回溯指 利用 DFS 找出从根节点到叶子节点的所有路径,只要有任意一条路径的 和 等于 sum,就返回 True。

下面的代码并非是严格意义上的回溯法,因为没有重复利用 path 变量。

Python 代码如下:

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if not root: return False
res = []
return self.dfs(root, sum, res, [root.val]) def dfs(self, root, target, res, path):
if not root: return False
if sum(path) == target and not root.left and not root.right:
return True
left_flag, right_flag = False, False
if root.left:
left_flag = self.dfs(root.left, target, res, path + [root.left.val])
if root.right:
right_flag = self.dfs(root.right, target, res, path + [root.right.val])
return left_flag or right_flag

BFS

BFS 使用 队列 保存遍历到每个节点时的路径和,如果该节点恰好是叶子节点,并且 路径和 正好等于 sum,说明找到了解。

Python 代码如下:

# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if not root:
return False
que = collections.deque()
que.append((root, root.val))
while que:
node, path = que.popleft()
if not node.left and not node.right and path == sum:
return True
if node.left:
que.append((node.left, path + node.left.val))
if node.right:
que.append((node.right, path + node.right.val))
return False

除了上面的 队列 解法以外,也可以使用 ,同时保存节点和到这个节点的路径和。但是这个解法已经不是 BFS。因为会优先访问 后进来 的节点,导致会把根节点的右子树访问结束之后,才访问左子树。

可能会有朋友好奇很少见到这种写法,为什么代码可行?答案是:栈中同时保存了 (节点,路径和),也就是说只要能把所有的节点访问一遍,那么就一定能找到正确的结果。无论是用 队列 还是 栈,都是一种 树的遍历 方式,只不过访问顺序有所有不同罢了。

Python 代码如下:

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if not root:
return False
stack = []
stack.append((root, root.val))
while stack:
node, path = stack.pop()
if not node.left and not node.right and path == sum:
return True
if node.left:
stack.append((node.left, path + node.left.val))
if node.right:
stack.append((node.right, path + node.right.val))
return False

日期

2017 年 5 月 12 日
2018 年 6 月 22 日
2018 年 11 月 24 日 —— 周六快乐
2020 年 7 月 7 日 —— 昨日 A 股涨了5.7%,5 年来的最高单日涨幅

【LeetCode】112. 路径总和 Path Sum 解题报告(Java & Python)的更多相关文章

  1. LeetCode 112. 路径总和(Path Sum) 10

    112. 路径总和 112. Path Sum 题目描述 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节 ...

  2. 【LeetCode】64. Minimum Path Sum 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  3. LeetCode: Binary Tree Maximum Path Sum 解题报告

    Binary Tree Maximum Path SumGiven a binary tree, find the maximum path sum. The path may start and e ...

  4. 【LeetCode】931. Minimum Falling Path Sum 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 相似题目 参考资料 日期 题目地址:htt ...

  5. 【LeetCode】459. Repeated Substring Pattern 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历子串 日期 [LeetCode] 题目地址:ht ...

  6. 【LeetCode】743. Network Delay Time 解题报告(Python)

    [LeetCode]743. Network Delay Time 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: ht ...

  7. 【LeetCode】486. Predict the Winner 解题报告(Python)

    [LeetCode]486. Predict the Winner 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: ht ...

  8. 【LeetCode】652. Find Duplicate Subtrees 解题报告(Python)

    [LeetCode]652. Find Duplicate Subtrees 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博 ...

  9. 【LeetCode】227. Basic Calculator II 解题报告(Python)

    [LeetCode]227. Basic Calculator II 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: h ...

随机推荐

  1. 毕业设计之zabbix+微信企业号报警

    需要自己申请一个微信企业号 创建应用 AgentId 1000003 Secret SOI8b20G96yUVM29K02-bP5N5o6dovwSF2RrDaXHJNg 企业ID(自己再企业信息里面 ...

  2. 在C++的map类型中按value排序

    1.将map转化为vector类型 2.使用sort函数对vector进行排序,写出compare比较器函数 3.比较器中指明按照第几个元素来排序 1 #include <iostream> ...

  3. Android 获取html中指定标签

    有时我们并不需要全部的html页面,而只是需要其中的部分标签,我们可以通过jsoup来完成这一操作. 官网:https://jsoup.org/ 1 Document document = Jsoup ...

  4. Hadoop fs.copyToLocalFile错误

    fs.copyToLocalFile(new Path("/study1/1.txt"), new Path("C:/Users/Administrator/Deskto ...

  5. nodeJs-querystring 模块

    JavaScript 标准参考教程(alpha) 草稿二:Node.js querystring 模块 GitHub TOP querystring 模块 来自<JavaScript 标准参考教 ...

  6. Oracle—数据库名、数据库实例名、数据库域名、数据库服务名的区别

    Oracle-数据库名.数据库实例名.数据库域名.数据库服务名的区别 一.数据库名 1.什么是数据库名       数据库名就是一个数据库的标识,就像人的身份证号一样.他用参数DB_NAME表示,如果 ...

  7. 一条查询SQL查询语句的执行原理

    先熟悉一下浅而易懂SQL执行的流程图SQL查询过程七步曲 1.查询SQL发送请求 客户端将查询sql按照mysql通信协议传输到服务端.服务端接受到请求后,服务端单起一个线程执行sql 2.判断是否为 ...

  8. Linux基础命令---vmstat显示虚拟内存状态

    vmstat vmstat指令用来显示虚拟内存使用状态,同时也可以显示进程.cpu活动情况.vmstat报告有关进程.内存.分页.块IO.陷阱和CPU活动的信息.生成的第一份报告给出了自上次重新启动以 ...

  9. Private Destructor

    Predict the output of following programs. 1 #include <iostream> 2 using namespace std; 3 4 cla ...

  10. oracle中分组中的ROLLUP和CUBE选项

    在进行多列分组统计时,如果直接使用GROUP BY子句指定分组列,则只能生成基于所有分组列的统计结果.如果在GROUP BY子句中使用ROLLUP语句或CUBE语句,除了生成基于所有指定列的分组统计外 ...