Algorithm 对节点进行分级

Algorithm 对节点进行分级,algorithm,data-structures,depth-first-search,greedy,Algorithm,Data Structures,Depth First Search,Greedy,最近我在一家公司做了一次编码面试测试。这是我无法解决的问题之一。我自己尝试过,但我不确定它是否正确,请帮助我纠正我在方法上的错误 这就是问题陈述:- 在这些节点中,有一个包含n个节点的树。该树在编号为0的节点上生根。在计算机科学中,通常情况下,与自然界中的树木相比,树木的生长是颠倒的。苹果生长在这棵树的节点上。这些苹果中有些水分不足,有些水分过多,还有一些两者都没有。你知道,对于每一个水分过多的苹果,你会得到水分过多的罚分,而对于每一个水分不足的苹果,你会得到水分不足的罚分。现在,您只需要在树的

最近我在一家公司做了一次编码面试测试。这是我无法解决的问题之一。我自己尝试过,但我不确定它是否正确,请帮助我纠正我在方法上的错误

这就是问题陈述:-

在这些节点中,有一个包含n个节点的树。该树在编号为0的节点上生根。在计算机科学中,通常情况下,与自然界中的树木相比,树木的生长是颠倒的。苹果生长在这棵树的节点上。这些苹果中有些水分不足,有些水分过多,还有一些两者都没有。你知道,对于每一个水分过多的苹果,你会得到水分过多的罚分,而对于每一个水分不足的苹果,你会得到水分不足的罚分。现在,您只需要在树的一个节点上浇水。当您在节点v上浇水时,v子树中的所有苹果,即vitself和v的所有后代,都将水合,因此,几乎水分过多的每个水合苹果都会变得水分过多。此外,整棵树上的每一个苹果,如果水分几乎不足,而且没有浇上水,就会水分不足。计算在树的一个节点上倒水所能得到的最小总惩罚

函数说明完成函数MinimumpouringWater罚则(向量父级、向量水位、int过水惩罚、int欠水惩罚)

MinimumpouringWaterPension具有以下参数:1。大小为n的整数数组parent,其中parenti表示第i个节点的父节点。2.一个整数数组,waterLevel,大小为n,其中waterLevel表示节点i上苹果中的水位。它是-1,0或1,其中-1代表几乎水分不足,O代表既不几乎水分不足也不几乎水分过多,1代表几乎水分过多。3.一个整数,过量水分惩罚,表示每个过量水分苹果的惩罚。4.一个整数,水分不足惩罚,表示每个水分不足苹果的惩罚

该函数必须返回在树的一个节点上浇水所能得到的最小惩罚

案文摘自:

我的做法:

from collections import defaultdict


def hyderatedtheNode(parent, waterLevel, overHyderatd, underHyderated):
    g = defaultdict(list)

    h_penalty = [0] * len(waterLevel)
    u_penalty = [0] * len(waterLevel)

    createGraph(parent, g)
    dfs(0, waterLevel, overHyderatd, underHyderated, 1, h_penalty, g)
    dfs(0, waterLevel, underHyderated, overHyderatd, - 1, u_penalty, g)
    # print(h_penalty)
    # print(u_penalty)
    # print(g)
    # print(list(enumerate(waterLevel)))
    ans = float('inf')
    p = u_penalty[0]
    for i, h in enumerate(h_penalty):
        ans = min(ans, h + (p - u_penalty[i]))
    print(ans)


def createGraph(parent, g):
    for i in range(1, len(parent)):
        g[parent[i]].append(i)


def dfs(src, waterLeve, oH, uH, apple, val, g):
    if not g.get(src, None):
        if waterLeve[src] == apple:
            val[src] = oH
            return oH
        return 0

    if g.get(src, None):
        penalty = 0
        if waterLeve[src] == apple:
            penalty = oH
        for t in g[src]:
            penalty += dfs(t, waterLeve, oH, uH, apple, val, g)
            # print(src, t, penalty)
    val[src] = penalty
    return penalty


hyderatedtheNode([-1, 0, 1], [1, 1, 1], 3, 5)  # 0
hyderatedtheNode([-1, 0, 0], [1, -1, -1], 10, 15)   # 10
hyderatedtheNode([-1, 0, 0, 1], [0, 0, 0, 0], 10, 15)  # 0 
hyderatedtheNode([-1, 0, 1, 0, 1, 2, 2, 2, 5, 5], [-1, -1, 0, -1, 0, 0, 1, 0, 0, 1], 2, 3)  # 4
  • 使用父级[i]->i(g)生成图形
  • 如果给每个节点水,则执行dfs遍历以检查该节点的惩罚。在本例中,仅检查是否有任何值为1,然后增加该节点的过度脱水的计数惩罚,并将每个节点的惩罚存储在数组中(h_惩罚
  • 再次横穿这一次检查,如果没有水,那么什么是罚款不足。在本例中,只需检查是否有任何值为-1,然后增加该节点的欠水压惩罚计数,并为每个节点存储(u_惩罚)如果给定水,则惩罚是什么
  • 现在,我有了每个节点的惩罚,若有水,若并没有水。然后我将遍历h_惩罚,对于每个节点,我将取h_惩罚[I]+(u_惩罚[0]-u惩罚[I])的最小值
  • 以下是我的方法代码:

    from collections import defaultdict
    
    
    def hyderatedtheNode(parent, waterLevel, overHyderatd, underHyderated):
        g = defaultdict(list)
    
        h_penalty = [0] * len(waterLevel)
        u_penalty = [0] * len(waterLevel)
    
        createGraph(parent, g)
        dfs(0, waterLevel, overHyderatd, underHyderated, 1, h_penalty, g)
        dfs(0, waterLevel, underHyderated, overHyderatd, - 1, u_penalty, g)
        # print(h_penalty)
        # print(u_penalty)
        # print(g)
        # print(list(enumerate(waterLevel)))
        ans = float('inf')
        p = u_penalty[0]
        for i, h in enumerate(h_penalty):
            ans = min(ans, h + (p - u_penalty[i]))
        print(ans)
    
    
    def createGraph(parent, g):
        for i in range(1, len(parent)):
            g[parent[i]].append(i)
    
    
    def dfs(src, waterLeve, oH, uH, apple, val, g):
        if not g.get(src, None):
            if waterLeve[src] == apple:
                val[src] = oH
                return oH
            return 0
    
        if g.get(src, None):
            penalty = 0
            if waterLeve[src] == apple:
                penalty = oH
            for t in g[src]:
                penalty += dfs(t, waterLeve, oH, uH, apple, val, g)
                # print(src, t, penalty)
        val[src] = penalty
        return penalty
    
    
    hyderatedtheNode([-1, 0, 1], [1, 1, 1], 3, 5)  # 0
    hyderatedtheNode([-1, 0, 0], [1, -1, -1], 10, 15)   # 10
    hyderatedtheNode([-1, 0, 0, 1], [0, 0, 0, 0], 10, 15)  # 0 
    hyderatedtheNode([-1, 0, 1, 0, 1, 2, 2, 2, 5, 5], [-1, -1, 0, -1, 0, 0, 1, 0, 0, 1], 2, 3)  # 4
    

    请让我知道这种方法是否合适,或者是否需要其他方法?

    应该说明您得到的错误类型。。。逻辑似乎是正确的,但您可以通过执行动态规划来优化dfs-由于节点之间存在分层关系,您可以通过首先计算每个子节点的计数来快速计算当前含水/脱水苹果的数量。我无法在测试中提交。我已经在h_惩罚和u_惩罚中存储了每个节点hyderated和Underhydrated惩罚的值。您是说只使用一次DFS遍历来计算两个数组值吗?