LeetCode139双周赛,换根DP

标记所有节点需要的时间
简单来说给一张有向图,找到每个节点的最大深度
找到一个节点的最大深度时,我们可以用一个简单的DFS,如果是每一个节点,需要用到DP
第一次dfs,找到每个节点向下的最大深度max_d,次大深度深度max_d2,最大深度节点的id,max_son_id
第二次dfs,为每个节点进行挑选,是选择往下走的最大深度呢,还是选择往上走的最大深度呢
from_up是个很重要的参数,他代表往上走的最大深度,当往下递归的时候,需要更新。父亲走到儿子,那么此时就应该以儿子为中心了,儿子往下的最大深度已经算出不用管了,来自父亲的最大深度需要更新,因为往上走的最大深度有可能来自父亲的父亲,也有可能来自父亲的儿子,即拐一个弯

class Solution:
    def timeTaken(self, edges: List[List[int]]) -> List[int]:
        g = [ [] for _ in range(len(edges) + 1) ]
        for x , y in edges:
            g[x].append(y)
            g[y].append(x)
        
        nodes = [None ]* len(g)
        def dfs(u:int, fa:int)->int:
            max_d = max_d2 = max_son_id = 0
            for j in g[u]:
                if j == fa:
                    continue
                depth = dfs(j, u) + (j + 1) % 2 + 1
                if depth > max_d:
                    max_d2 = max_d
                    max_d = depth
                    max_son_id = j
                elif depth > max_d2:
                    max_d2 = depth
            nodes[u] = (max_d,max_d2, max_son_id)
            return max_d

        dfs(0, -1)
        ans = [0] * len(g)
        print(nodes)
        def reroot(u:int, fa:int, from_up:int) -> None:
            max_d, max_d2, max_son_id = nodes[u]
            ans[u] = max(from_up, max_d)
            for j in g[u]:
                if j == fa:continue
                up1 = from_up 
                up2 = (max_d2 if j == max_son_id else max_d)
                # from_up也有两类,一类是还是父亲的from_up,另一类是父亲中儿子最出色的
                reroot(j, u, max(up1, up2) + (u + 1) % 2 + 1 )
        reroot(0, -1, 0)
        return ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值