113. 二叉树路径总和 II 124. 二叉树中的最大路径和

88 篇文章 0 订阅
26 篇文章 0 订阅
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1
返回:
[
   [5,4,11,2],
   [5,8,4,5]
]

解题思路

使用深度优先遍历到每一个叶子节点。

# 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 pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: List[List[int]]
        """
        res = []
        if root == None:
            return res 
        def dfs(root, state, target):
            # print(state, target)
            # 必须遍历到叶子节点才可以
            if target == root.val and root.left == None and root.right == None:
                res.append(state + [root.val])
                return 
            else:
                # state.apend(root.val)
                # target -= root.val 
                if root.left != None:
                    dfs(root.left, state + [root.val], target - root.val)

                if root.right != None:
                    dfs(root.right, state + [root.val], target - root.val)

        dfs(root, [], sum)
        return res 

124. 二叉树中的最大路径和

给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。
该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入: [1,2,3]
       1
      / \
     2   3
输出: 6
示例 2:
输入: [-10,9,20,null,null,15,7]
   -10
   / \
  9  20
    /  \
   15   7

输出: 42

解题思路

二叉树 abc,a 是根结点(递归中的 root),bc 是左右子结点(代表其递归后的最优解)。
最大的路径,可能的路径情况:

    a
   / \
  b   c

1、b + a + c。
2、b + a + a 的父结点。
3、a + c + a 的父结点。
其中情况 1,表示如果不联络父节点的情况,或本身是根节点的情况。这种情况是没法递归的,但是结果有可能是全局最大路径和。
情况 2 和 3,递归时计算 a+b 和 a+c,选择一个更优的方案返回,也就是上面说的递归后的最优解啦。
另外节点有可能是负值,最大和肯定就要想办法舍弃负值(max(0, x))。
但是上面 3 种情况,无论哪种,a 作为联络点,都不能够舍弃。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
'''
    a
   / \
  b   c
最大路径的情况有三种
1、b + a + c。
2、b + a + a 的父结点。
3、a + c + a 的父结点。
'''
class Solution(object):
    def maxPathSum(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if root == None:
            return 0 
        
        # 用于记录最大值
        self.maxSum = -float('inf') 
        # 返回经过root的单边分支最大和, 即max(root, root + left, root + right)
        def dfs(root):
            if root == None:
                return 0 
            else:
                # 计算当前节点的左右分支的值,如果小于0,还不如不选择,但是当前节点作为联络点,不能够舍弃 
                # 计算左边分支最大值,左边分支如果为负数还不如不选择,即必要左分支只要当前节点
                leftmax = max(dfs(root.left), 0)
                # 计算右边分支最大值,右边分支如果为负数还不如不选择
                rightmax = max(dfs(root.right), 0)

                # left->root->right 作为路径与历史最大值做比较,不向root的父结点延伸
                self.maxSum = max(self.maxSum, root.val + leftmax + rightmax)
                # 返回经过root的单边最大分支给上游(即root的父节点) 
                return root.val + max(leftmax, rightmax)

        dfs(root)
        return self.maxSum
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值