【发布时间】:2015-02-17 14:01:24
【问题描述】:
有一个m*n 矩阵,我们需要找到从左上角到右下角的所有可能路径。
只能沿右下方向遍历。
我有以下疑惑:
在递归方法中,我知道时间复杂度将为 O(2(m+n))。如何使用归纳法获得它?
如何找到动态规划解决方案的复杂性?
【问题讨论】:
标签: recursion data-structures time-complexity dynamic-programming
有一个m*n 矩阵,我们需要找到从左上角到右下角的所有可能路径。
只能沿右下方向遍历。
我有以下疑惑:
在递归方法中,我知道时间复杂度将为 O(2(m+n))。如何使用归纳法获得它?
如何找到动态规划解决方案的复杂性?
【问题讨论】:
标签: recursion data-structures time-complexity dynamic-programming
对于第一个没有记忆的问题:
1) 在递归方法中,我知道时间复杂度为 O(2(m+n))。如何使用归纳法获得它?
当我们在一棵二叉树中表示递归函数的连续调用时,在每一层k 代表kth 移动——0 代表二叉树的根,起始位置 — 该函数在k + 1th 楼层进行两次新的递归调用。此外,如sachas's answer 中所述,所有路径都会有m-1 水平移动和n-1 垂直移动。因此有(m-1)(n-1) 楼层,每个可能的kth 移动一个。
那么,因为:
(m-1)(n-1)层,因此有 20 + 20 + ... + 2(m - 1)(n - 1) = 2 (m - 1)(n - 1) + 1 - 函数调用1次(按几何数列求和公式),递归函数时间复杂度O(1),则复杂度为O(2(m - 1)(n - 1) + 1) = O( 2mn)。结果就是这样。
【讨论】:
在动态编程中,您尝试填充数组 dp[i][j] 其中 dp[i][j] 表示到达单元格的方式数(i ,j) 从左上角的单元格。还有 dp[i][j]=dp[i][j-1]+dp[i-1][j] ,(避免 i=1 或 j=1 的极端情况) .所以总的来说,你必须用 n*m 条目填充 dp 表,每个条目取决于恒定数量的条目(最多 2 个)dp[i-1][j]强> 和 dp[i][j-1]。因此复杂度将是 O(2*n * m),即 O(n*m)。
其次,如果我们不做 dp 或 memoization(可以 goole 它)并递归地做,那么你基本上是在找到计数的同时跟踪所有可能的路径。因此复杂性将是从左上角单元格到右下角的路径数。所有路径都会有 m-1 水平移动和 n-1 垂直移动。因此路径数变为 (m+n-2)! / ( (m-1)! * (n-1)!)。这是复杂性,而不是您建议的指数。
【讨论】: