Python 使用两个堆栈的解决方案

Python 使用两个堆栈的解决方案,python,math,stack,Python,Math,Stack,我正在尝试来自Hackerrank的相等堆栈问题: 有人能帮我理解下面两个代码的逻辑区别吗。第一个失败,另一个成功: 首先(我的解决方案): 第二种解决方案(正确): 我知道在第二个例子中,我们正在反转输入数组。但这会有什么不同吗 我完全困惑不解 请帮助我指出第一个代码的问题所在 提前感谢。订购事宜 我知道在第二个例子中,我们正在反转输入数组。但这会有什么不同吗 是的这会产生影响。假设您有以下堆栈: 1 1 2 1 1 1 3 我们必须弹出正确的堆栈,因为它是最大的堆栈。但我们只能从中弹

我正在尝试来自Hackerrank的相等堆栈问题:

有人能帮我理解下面两个代码的逻辑区别吗。第一个失败,另一个成功:

首先(我的解决方案):

第二种解决方案(正确):

我知道在第二个例子中,我们正在反转输入数组。但这会有什么不同吗

我完全困惑不解

请帮助我指出第一个代码的问题所在

提前感谢。

订购事宜 我知道在第二个例子中,我们正在反转输入数组。但这会有什么不同吗

是的这会产生影响。假设您有以下堆栈:

1
1  2  1
1  1  3
我们必须弹出正确的堆栈,因为它是最大的堆栈。但我们只能从中弹出
3
(黑体)。因此,最大高度只能为
1
。当我们弹出
3
时,我们稍后会发现,我们可以获得的最大等高是
0
。如果我们弹出正确的堆栈,我们将获得:

1
1  1
1  2  1
但是中间的堆栈底部有2个。因此,我们不能在中间产生一个1的总和。 堆栈意味着一个顺序:我们必须先移除圆柱体上方的元素,然后才能弹出该元素,因此顺序很重要

为什么第一个不起作用。 在第一个代码片段中,从堆栈的总和中减去第一个元素。但是您不能从列表中删除该元素。因此,您会不断从堆栈中弹出第一个元素

您可以通过
pop(0)
(从列表开头弹出)或稍后删除该元素来修复它:

# fix of the first code fragment

while not (sum_h1 == sum_h2 and sum_h2 == sum_h3):
    if sum_h1 > sum_h2 or sum_h1 > sum_h3:
        sum_h1 -= H1.pop(0)
        #print ("Checking:",sum_h1)
    if sum_h2 > sum_h1 or sum_h2 > sum_h3:
        sum_h2 -= H2.pop(0)
    if sum_h3 > sum_h1 or sum_h3 > sum_h2:
        sum_h3 -= H3.pop(0)
#修复第一个代码片段
而不是(sum_h1==sum_h2和sum_h2==sum_h3):
如果sum_h1>sum_h2或sum_h1>sum_h3:
sum_h1-=h1.pop(0)
#打印(“检查:”,求和h1)
如果sum_h2>sum_h1或sum_h2>sum_h3:
sum_h2-=h2.pop(0)
如果sum_h3>sum_h1或sum_h3>sum_h2:
sum_h3-=h3.pop(0)
或:

#修复第一个代码片段
而不是(sum_h1==sum_h2和sum_h2==sum_h3):
如果sum_h1>sum_h2或sum_h1>sum_h3:
sum_h1-=h1[0]
德尔H1[0]
#打印(“检查:”,求和h1)
如果sum_h2>sum_h1或sum_h2>sum_h3:
sum_h2-=h2[0]
del H2[0]
如果sum_h3>sum_h1或sum_h3>sum_h2:
sum_h3-=h3[0]
删除H3[0]

但是请注意,这些都是低效的:从一开始弹出是一个O(n)操作,n是列表的大小。

您的解决方案和正确的解决方案之间的区别在于堆栈是反向的。在这种情况下,您应该调用
list.pop(0)
删除第一个元素

while not (sum_h1 == sum_h2 and sum_h2 == sum_h3):
    if sum_h1 > sum_h2 or sum_h1 > sum_h3:
        t = H1.pop(0) # -------------- pop 0th element 
        sum_h1 -= t  
    if sum_h2 > sum_h1 or sum_h2 > sum_h3:
        t = H2.pop(0)  # -------------- pop 0th element 
        sum_h2 -= t
    if sum_h3 > sum_h1 or sum_h3 > sum_h2:
        t = H3.pop(0)  # -------------- pop 0th element 
        sum_h3 -= t
print (sum_h1)
对于此输入:

5 3 4
3 2 1 1 1
4 3 2
1 1 4 1
这是输出:

5

因为@Willem Van Onsem和@coldspeed解释了第一个解决方案与另一个不同,我想我可以解释一个类似的解决方案,更容易理解(在我看来)

假设堆栈与原始问题相同:

3 2 1 1 1  (stack1)
4 3 2      (stack2)
1 1 4 1    (stack3)
在这里,最左边的数字是每个堆栈的顶部,最右边的是底部。我选择第一个堆栈作为参考堆栈(但它可以是三个堆栈中的任意一个)。拆卸气缸时,其可能的高度为
8、5、3、2、1、0
。我们的任务是尝试所有的高度,看看它们是否可以是普通的。然后,最大公共高度就是答案

让我们自下而上解决这个问题。因此,堆栈是空的,我们希望从一开始就构建它们。在构建它们时,我们将找到所有高度相等的堆栈配置。因此,具有最大高度的配置将是问题的答案

  • 每个堆栈的初始最大公共高度以及当前高度为
    0

    0
    0
    0
    0 (max)
    
  • 1
    添加到
    stack1
    的高度。然后,因为
    stack2
    的当前高度小于
    stack1
    的当前高度,所以通过对底部元素求和来增加它。对堆栈3执行相同的操作

    1
    2
    1
    0 (max)
    
    由于高度不同,最大值保持
    0
    。因此,
    1
    不能是堆栈的常见高度

  • 1
    添加到
    stack1
    的高度<代码>堆栈2的高度相等,所以不要对其进行任何操作。对于
    stack3
    ,只要高度小于此值,就继续求和

    2
    2
    5
    0 (max)
    
  • 输出最大高度,因为第一个堆栈为空,而使用其他堆栈(如果它们仍然为非空)没有意义

  • 现在,算法本身(为了简单起见,在
    Python3
    中):

    n,m,k=map(int,input().split())
    stack1=list(映射(int,input().split())
    stack2=list(映射(int,input().split())
    stack3=list(映射(int,input().split())
    最大高度=0
    高度1=0
    高度2=0
    高度3=0
    而len(stack1)>0:
    如果len(stack1)>0:
    高度1+=stack1.pop()
    当len(stack2)>0且高度2<1时:
    height2+=stack2.pop()
    当len(stack3)>0且高度3<1时:
    高度3+=stack3.pop()
    如果高度1==高度2==高度3:
    最大高度=高度1
    打印(最大高度)
    
    您的逻辑是正确的,除了在OP的解决方案中,他正在索引
    H[0]
    ,所以他仍然在减去1。我认为顺序不是问题。OP没有调用
    H.pop(0)
    @Coldspeed:但是
    pop()
    pops从列表的右侧(也就是堆栈的顶部)弹出。这就是第一个失败而第二个成功的原因。
    pop(0)
    pops从一开始。在OP的堆栈反转的情况下,
    pop(0)
    是正确的操作,OP没有这样做(从我看到的)<代码>>>>x=[1,2,3];>>>x、 pop(0);1@Coldspeed:我没有注意到列表在第一个代码片段中没有反转。固定的。
    3 2 1 1 1  (stack1)
    4 3 2      (stack2)
    1 1 4 1    (stack3)
    
    0
    0
    0
    0 (max)
    
    1
    2
    1
    0 (max)
    
    2
    2
    5
    0 (max)
    
    3
    5
    5
    0 (max)
    
    3
    5
    5
    0 (max)
    
    5
    5
    5
    5 (max)
    
    8
    9
    10
    5 (max)
    
    5 (max)
    
    n, m, k = map(int, input().split())
    stack1 = list(map(int, input().split()))
    stack2 = list(map(int, input().split()))
    stack3 = list(map(int, input().split()))
    
    max_height = 0
    height1 = 0
    height2 = 0
    height3 = 0
    
    while len(stack1) > 0:
        if len(stack1) > 0:    
            height1 += stack1.pop() 
        while len(stack2) > 0 and height2 < height1:
            height2 += stack2.pop()        
        while len(stack3) > 0 and height3 < height1:
            height3 += stack3.pop()  
    
        if height1 == height2 == height3:
            max_height = height1     
    
    print (max_height)