leetcode-112 | 路径总和

title: leetcode-112 | 路径总和
date: 2019-10-12 08:54:20
comments: true
categories: “leetcode”
tags:
- leetcode 简单难度

112. 路径总和

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

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

示例:
给定如下二叉树,以及目标和sum = 22
leetcode-112 | 路径总和_第1张图片
返回 true, 因为存在目标和为22 的根节点到叶子节点的路径 5->4->11->2

思路

想了半天,总是不知道该如何表达这个算法的逻辑。
就看了解答区,官方解答思路如下图:
leetcode-112 | 路径总和_第2张图片

代码实现

然后自己根据上面图片的思路,修修改改了好几次才做出来。
需要注意的是:
不是说一定有sum>root.left.val或者sum>root.right.val,题中所举的案例只是一部分。
如:[1,-2,-3,1,3,-2,null,-1] sum=-1 结果是True
比较容易误判,故而就不去判断sum和节点值得大小来决定是否退栈操作。

class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution(object):
    def __init__(self):
        # 初始化一个类的全局栈
        self.stack = []

    # 是否是叶子节点
    def isleaft(self, node):
        if node.left is None and node.right is None:
            return True
        return False


    def hasPathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: bool
        """
        #
        if root is None:
            return False

        self.stack.append([root, sum - root.val])
        while len(self.stack):
            i = len(self.stack)
            while i > 0:
                top = self.stack.pop()
                current_root = top[0]
                current_sum = top[1]
                print(current_root.val, current_sum)
                # 判断是否是叶节点
                if self.isleaft(current_root) and current_sum == 0:
                    return True
                # 非叶子节点,判断是否含有左右孩子
                if current_root.left:
                    self.stack.append([current_root.left, current_sum - current_root.left.val])
                if current_root.right:
                    self.stack.append([current_root.right, current_sum - current_root.right.val])
                i = i - 1
        # 没有叶子节点,满足sum=0,那么也就是查找失败
        return False

if __name__ == '__main__':
    # a = [1,-2,-3,1,3,-2,null,-1]
    a = TreeNode(1)
    b = TreeNode(-2)
    c = TreeNode(-3)
    d = TreeNode(1)
    e = TreeNode(3)
    f = TreeNode(-2)
    g = TreeNode(-1)
    a.left = b
    a.right = c
    b.left = d
    b.right = e
    c.left = f
    d.left = g

    print(Solution().hasPathSum(a, -1))

结果:
leetcode-112 | 路径总和_第3张图片

思考

由于上面的代码的效率并不是很高,所以这里我们还需要思考如何优化?
看了看,大部分提交者的代码都是利用递归:

最直接的方法就是利用递归,遍历整棵树:如果当前节点不是叶子,对它的所有孩子节点,递归调用 hasPathSum 函数,其中 sum 值减去当前节点的权值;如果当前节点是叶子,检查 sum 值是否为 0,也就是是否找到了给定的目标和。

# 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
        
        else:
            if not root.left and not root.right:
                return root.val - sum == 0
            else:
                sum -= root.val
                return self.hasPathSum(root.left,sum) or self.hasPathSum(root.right,sum)

果然,效果比较好:
leetcode-112 | 路径总和_第4张图片

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-sum

你可能感兴趣的:(#,leetcode,简单难度,leetcode刷题集合)