在二叉树中找到累加和为指定值的最长路径长度

Description

给定一颗二叉树和一个整数 sum,求累加和为 sum 的最长路径长度。路径是指从某个节点往下,每次最多选择一个孩子节点或者不选所形成的节点链。

分析

题目的意思是:这道题在求路径和为sum的基础上加了一个限制条件,即路径必须最长。所以在找到符合条件的路径的时候,要判断路径的长度,这时可以利用字典来存储信息,字典存放的是根结点到当前节点的累加和和层数的映射。

  • 字典首先添加{0:0}记录,表示累加和为0不用任何节点就可以得到。然后先序遍历二叉树,假设遍历到的当前位置是cur,层数为level,此时的累加和应为cur的父节点的累加和presum加上cur节点的值,即cursum = presum + cur.val。

  • 如果(presum + cur.val, level)这个记录已经存在于字典中,则不需要再次插入。接下来,判断是否有以cur结尾的路径的累加和等于题目所给的指定值sum。只需要在map中寻找是否有cursum - sum这个记录即可,如果存在这个记录的话 level - d[cursum - sum]就是满足条件的一个路径长度,使用全局变量更新路径的最大值。

  • 需要注意的是,在遍历完二叉树的子树要返回到cur的父节点是,需要将map中该节点的记录删去(如果之前插入的话),否则可能出现路径不是自顶向下的情况。

这道题出自左神写的程序员面试指南,思路还是比较新颖的,我学习一下思路。

代码


import collections

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

def solve(root,K,preSum,level,l,d):
    if(root is None):
        return l
    curSum=preSum+root.val
    if(curSum not in d):
        d[curSum]=level
        # print(d)
    if(curSum-K in d):
        l=max(level-d[curSum-K],l)
    l=solve(root.left,K,curSum,level+1,l,d)
    l=solve(root.right,K,curSum,level+1,l,d)
    if(level==d[curSum]):
        d.pop(curSum)
    return l

def getMaxLength(root,K):
    d=collections.defaultdict(int)
    d[0]=0
    return solve(root,K,0,1,0,d)

if __name__ == "__main__":
    vals = [-3, 3, -9, 1, 0, 2, 1, 1, 6]
    nodes = [TreeNode(v) for v in vals]

    root = nodes[0]
    nodes[0].left, nodes[0].right = nodes[1], nodes[2]
    nodes[1].left, nodes[1].right = nodes[3], nodes[4]
    nodes[2].left, nodes[2].right = nodes[5], nodes[6]
    nodes[4].left, nodes[4].right = nodes[7], nodes[8]

    assert(getMaxLength(root, 6) == 4)
    assert(getMaxLength(root, -9) == 1)
    assert(getMaxLength(root, -10) == 3)
    assert(getMaxLength(root, -11) == 3)
    assert(getMaxLength(root, 4) == 3)
    assert(getMaxLength(root, 1) == 4)
    assert(getMaxLength(root, 3) == 2)

参考文献

[编程题]在二叉树中找到累加和为指定值的最长路径长度
二叉树中累加和为指定值的最长路径
二叉树问题—在二叉树中找到累加和为指定值的最长路径长度
在二叉树中找到累加和为指定值的最长路径长度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

农民小飞侠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值