【问题标题】:Exercise 1.3.45 (Algorithms 4th edition by Robert Sedgewick) PROBLEM练习 1.3.45(Robert Sedgewick 的算法第 4 版)问题
【发布时间】:2021-03-06 18:53:43
【问题描述】:

--------问题陈述------------- ---

1.3.45 堆栈可生成性。假设我们有一系列混合的 push 和 pop 操作,就像我们的测试堆栈客户端一样,其中整数 0、1、...、N-1 按该顺序(push 指令)与 N 个减号(pop 指令)混合.设计一种算法来确定混合序列是否会导致堆栈下溢。 (您只能使用与 N 无关的空间量——您不能将整数存储在数据结构中。)设计一个线性时间算法来确定是否可以将给定的排列生成为我们的测试客户端的输出(取决于pop 指令发生)。

解决方案:堆栈不会溢出,除非存在整数 k 使得前 k 个弹出操作发生在前 k 个压入操作之前。如果可以生成给定的排列,则唯一生成如下:如果输出排列中的下一个整数在栈顶,则将其弹出;否则,将其压入堆栈。


我对这部分的理解只有一个问题:设计一个线性时间算法,确定是否可以将给定的排列生成为我们的测试客户端的输出(取决于 pop 指令出现的位置)。

我在 google 上看到了有关如何解决此练习的解决方案,但我找不到有关如何解决的解释。谁能解释一下?谢谢

【问题讨论】:

  • 我在 google 上看到有解决方案 - 请发布一个您想获得解释的解决方案。见How to Ask

标签: algorithm stack


【解决方案1】:

第一步非常简单。为了确定一系列步骤是否导致上溢或下溢,我们使用以下算法,其中 k 是堆栈的大小限制,指令列表是 PUSH 或 POP 列表:

在 Python 中:

def undeflows(lst):
    count = 0
    for x in lst:
        if x == PUSH:
            count += 1
        else:
            # We know that x == POP
            if count == 0:
                return True
            count -= 1
    return False

对于第二部分,关键是我们可以推断产生给定输出的操作顺序必须是什么。考虑以下算法:

在 Python 中:

def test_permutation(perm):
    stack = []
    next_to_read = 0
    for val in perm:
        if val >= next_to_read:
            # in this case, we haven't pushed val yet. We'll need to push
            # next_to_read to val inclusive, then pop val.
            stack.extend(range(next_to_read, val))
            next_to_read = val + 1
        # Otherwise, we must have already pushed val. We must check to make sure
        # we can pop it.
        elif stack and stack[-1] == val:
            stack.pop()
        else:
            return False
    # at this point, stack should be empty.
    return not stack

如果我们保证输入实际上是0、1、...、n-1的排列,那么我们可以修改代码为

def test_permutation(perm):
    stack = []
    next_to_read = 0
    for val in perm:
        if val >= next_to_read:
            # in this case, we haven't pushed val yet. We'll need to push
            # next_to_read to val inclusive, then pop val.
            stack.extend(range(next_to_read, val))
            next_to_read = val + 1
        # Otherwise, we must have already pushed val. We must check to make sure
        # we can pop it.
        elif stack[-1] == val:
            stack.pop()
        else:
            return False
    # at this point, stack should be empty.
    return True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2021-06-15
    • 1970-01-01
    • 2016-06-29
    相关资源
    最近更新 更多