LeetCode-路径总和-总结

Leetcode 112:路径总和

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

输入:
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1

输出:返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

这个问题太简单了,我们只要搞清楚什么时候才是叶子节点,这个问题就解决了。当node.left==None and node.right==None的时候,node就是叶子节点。

实现:

class Solution:
    def hasPathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: bool
        """
        if not root:
            return False

        if not (root.left or root.right):
            return sum == root.val

        return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)

Leetcode 113:路径总和 II

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径
示例:

输入:
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1    

输出:
[
   [5,4,11,2],
   [5,8,4,5]
]

当访问的节点是叶子节点的时候,我们新建一个list,插入到result中,然后返回result。
分别遍历左右子树的节点,然后将他们分别插入到叶子节点之前就可以了。

实现:(经典回溯模板问题)

class Solution(object):
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: List[List[int]]
        """
        # 回溯
        if not root:
            return []
        
        res = []
        
        self.backtrack(root, list(), sum, res)
        return res
    
    def backtrack(self, current_node, path, target, res):
        if not current_node:
            return None
        path.append(current_node.val)
        if current_node.val == target and not (current_node.left or current_node.right):
            res.append(path[:])    #res.append(path.copy())
        self.backtrack(current_node.left, path, target-current_node.val, res)
        self.backtrack(current_node.right, path, target-current_node.val, res)
        path.pop()

Leetcode 437:路径总和 III

给定一个二叉树,它的每个结点都存放着一个整数值。
找出路径和等于给定数值的路径总数。
路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

实例:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

返回 3。和等于 8 的路径有:

1.  5 -> 3
2.  5 -> 2 -> 1
3.  -3 -> 11

这个问题非常有意思。和之前问题

Leetcode 112:路径总和(最详细的解法!!!)

Leetcode 113:路径总和 II(最详细的解法!!!)

的区别在于,这个问题不一定是从根节点出发。知道这一点的话,我们很容易写出:

def pathSum(self, root, sum):
    """
        :type root: TreeNode
        :type sum: int
        :rtype: int
        """
    result = 0
    if not root:
        return result

    result += self.dfs(root, sum)
    result += self.pathSum(root.left, sum)
    result += self.pathSum(root.right, sum)
    return result

分析:题目要求在以root为根结点的二叉树中,寻找和为sum的路径,返回这样的路径个数。
我们可以分两种情况进行递归遍历,

第一种:sum包含当前结点,在他的左右子树里面寻找和为sum的路径数量。递归调用dfs
第二种:当前结点不包含在sum里面,直接调用pathSum递归

实现:

class Solution(object):
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: int
        """
        result = 0
        if not root:
            return result
        
        result += self.dfs(root, sum)    # 包含该节点的路径(就是dfs)
        result += self.pathSum(root.left, sum)    # 不包含该节点的路径
        result += self.pathSum(root.right, sum)    
        return result
    
    def dfs(self, node, sum):
        result = 0
        if not node:
            return result
        if node.val == sum:
            result += 1
        result += self.dfs(node.left, sum-node.val)
        result += self.dfs(node.right, sum-node.val)
        return result

1000 ms, 在所有 Python 提交中击败了39.14%的用户 太慢了!!!

你可能感兴趣的:(算法,刷题)