【问题标题】:Iterative, bottom up, divide and conquer algorithm迭代、自下而上、分而治之的算法
【发布时间】:2020-08-10 13:50:51
【问题描述】:

我正在阅读这个LeetCode article 的常见算法问题“最长公共前缀”。他们展示了几种不同的方法,但我的问题仅与“分而治之”有关。它的示例显示了您经常在各处的书籍和博客中看到的典型递归自上而下方法。

看到这让我想到我应该能够“迭代”和“自下而上”地做到这一点。类似于自下而上的合并排序方法。所以这就是我结束的地方:

// type "Stack", function "prefix", and "min" implementations are not shown for brevity.
// Just assume they're defined somewhere and they work correctly.
//
// "prefix" function accepts two strings and returns a string
// Examples:
// prefix("abcd", "ab") returns "ab"
// prefix("abcd", "efgh") returns ""
// ... you get the idea.
//
// "min" does exactly what you'd expect. Its arguments are both type int.
func lcpDAndC(a []string) string {
        n := len(a)

        if n == 0 {
                return ""
        }

        var (
                stack Stack
                p, q  string
        )
        for lo := 0; lo < n; lo += 2 {
                hi := min(lo+1, n-1)
                stack = stack.Push(prefix(a[lo], a[hi])
        }

        for stack.Len() > 1 {
                p, q = stack.Pop2()
                stack.Push(prefix(p, q))
        }

        return stack.Pop1()
}

所以我的问题是:这仍然被认为是“自下而上”和“分而治之”吗?我认为可以安全地假设立即从叶子开始(自下而上的部分)只需一次处理两个元素,因为它通过数组一次(“划分”......但也是“征服? ”)。这里的堆栈当然与递归方法中的调用堆栈发挥相同的作用。不过,队列也可以,这也是我认为我在这里走得太远的另一个原因。

如果这不是“自下而上”和“分而治之”的正确应用,这是否至少应用了一些我不知道的其他理论?

【问题讨论】:

    标签: algorithm prefix divide-and-conquer bottom-up


    【解决方案1】:

    本文中使用的递归是Top Down,因为它们将较大的情况分解为较小的情况,然后将较小情况的结果组合起来。

    在递归中,函数调用相互叠加到函数调用堆栈中。它们也被弹出

    (1) Once the base case is reached

    (2) Results of function calls above them in the stack has been computed and it's their turn now.

    您的代码没有执行Bottom Up 递归,也不是D&amp;C

    考虑这种情况:-

    ["care","car","cat","cater","click","clang","core","coral"]

    最初堆栈:-

    cor
    cl
    cat
    car
    

    While 循环迭代 #1:

    c
    cat
    car
    

    While 循环迭代 #2:

    c
    car
    

    While 循环迭代 #3:

    c
    

    您的 while 循环以串行方式组合元素,并且不使用 D&amp;C 的属性。如果将 for 循环中的 lo+=2 更改为 lo+=1,则您的代码与 Approach 1: Horizontal scanning 相同。

    但是,使用队列会使代码成为Bottom-Up 递归。 请注意,每次弹出两个元素时,它们代表两个相互排斥的半部分,这两个部分也可以在 Top Down 方法的递归树中找到。 考虑这种情况:-

    ["care","car","cat","cater","click","clang","core","coral"]

    最初排队:-

    cor
    cl
    cat
    car
    

    While 循环迭代 #1:

    ca
    cor
    cl
    

    While 循环迭代 #2:

    c
    ca
    

    While 循环迭代 #3:

    c
    

    【讨论】:

      猜你喜欢
      • 2013-02-02
      • 1970-01-01
      • 2012-01-01
      • 2019-06-12
      • 2013-02-03
      • 2017-06-08
      • 1970-01-01
      • 2017-04-07
      • 2013-03-17
      相关资源
      最近更新 更多