【问题标题】:What is the time complexity of following grid traversal function?跟随网格遍历函数的时间复杂度是多少?
【发布时间】:2021-12-20 14:02:41
【问题描述】:

我正在接受面试培训,并发现了一个小测验,即在网格中有一些石头的情况下找到出口的最低成本(你不能在出口路径内使用带有石头的单元格)。

我可以做这些问题,但我正在努力解决我的算法的时间复杂度(作为一个整体/两个函数)。希望这里有人能照亮它。

我天真地猜测为:O(4^row*col)

我们递归地进行 DFS,在每个单元格上,我们可以分支到四个方向(上、右、下、左)。我们不会严格访问每个单元一次。

但单元格上的值是一种记忆,不是吗?

我的意思是使用O(n) 进行记忆的斐波那契递归,因为我们不会对我们计算过的数字进行重复计算。

我们可以将每个单元格上的值计算为记忆吗?因为如果它更小,它会在每次迭代中更新

func findMinStepsToExit(input [][]int) int {
    if input == nil {
        return -1
    }

    lenRow := len(input)
    lenCol := len(input[0])

    if lenRow == 1 && lenCol == 1 {
        return 0
    }

    helper(input, 0, 0, lenRow, lenCol, 0)

    ans := input[lenRow-1][lenCol-1]

    if ans <= 1 {
        return -1
    }

    return ans

}
func helper(grid [][]int, row, col, lenRow, lenCol, currStep int) {
    if row < 0 || col < 0 || row > lenRow || col > lenCol || grid[row][cell] == 0 {
        return
    }

    var newStep int
    if grid[row][cell] != 1 {
        newStep == currStep+1

        if newStep > grid[row][cell] {
            return
        }

        grid[row][cell] = newStep
    }

    if grid[row][cell] == 1 {
        grid[row][cell] == currStep+1
    }

    helper(grid, row+1, col, lenRow, lenCol, currStep+1) // bottom
    helper(grid, row, col+1, lenRow, lenCol, currStep+1) // right
    helper(grid, row-1, col, lenRow, lenCol, currStep+1) // top
    helper(grid, row, col-1, lenRow, lenCol, currStep+1) // left

    return
}

【问题讨论】:

    标签: algorithm time-complexity big-o dynamic-programming


    【解决方案1】:

    我认为使用 BFS 而不是 DFS 会更好。 (你需要一个步骤来检查你是否在每次迭代中踩到了石头,而不是从那个地方走得更远,例如通过标记它。)

    如果您必须在找到出口之前检查并标记每个单元格,则时间和空间复杂度为 O(x*y)。

    这让我想起了Dijkstra algorithm。也许看看

    【讨论】:

    • 是的,我知道它没有那么可扩展,但只想知道它的时间复杂度。想想它是决定时间复杂度的训练,而不是设计更好的算法。它不可能是O(x*y) -> 这很好。对 top、bottom、left 和 right 的每个递归调用呢?
    【解决方案2】:

    这个算法是指数的,不幸的是,如果你想在指数函数上得到一个严格的渐近界,你必须得到指数完全正确。对于这个算法来说,这将是相当困难的——不值得麻烦。指数太慢了。

    但单元格上的值是一种记忆,不是吗?

    确实如此,但没有得到有效使用。但是,如果您进行一点小改动,一切都会改变,从 if newStep &gt; grid[row][cell]if newStep &gt;= grid[row][cell]

    然后,您的算法变成多项式。考虑到所花费的总时间与您进行的单元格更新数量成正比。由于每个单元格最初最多更新到rows*cols,并且每次更新从那里减少到最少1,因此每个单元格最多有rows*cols更新,总时间变为O((rows*cols) 2)。

    它仍然不是一个很好的算法。您应该使用广度优先搜索 O(rows*cols)。

    【讨论】:

    • 指数是:O(branches^n),即:O(2^N),二次是:O(n^2) 不是吗?我只关注时间复杂度,我们如何为此提出正确的时间复杂度,而不是设计更好的算法。
    猜你喜欢
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 2017-09-11
    • 2020-03-13
    相关资源
    最近更新 更多