Algorithm 我可以将任何递归代码转换为递归关系吗?

Algorithm 我可以将任何递归代码转换为递归关系吗?,algorithm,time-complexity,big-o,recurrence,Algorithm,Time Complexity,Big O,Recurrence,所以我一直在youtube上学习动态编程,这里是链接,我在grid Traveler递归部分学习。但我仍然对时间的复杂性感到困惑 例如,此网格移动器递归方法: int gridTraveler(int m, int n) { if (m == 0 || n == 0) { return 0; } if (m == 1 || n == 1) { return 1; } return gridTraveler(m - 1, n) + gridTraveler(m,

所以我一直在youtube上学习动态编程,这里是链接,我在grid Traveler递归部分学习。但我仍然对时间的复杂性感到困惑

例如,此网格移动器递归方法:

int gridTraveler(int m, int n) {
  if (m == 0 || n == 0) {
    return 0;
  }
  if (m == 1 || n == 1) {
    return 1;
  }
  return gridTraveler(m - 1, n) + gridTraveler(m, n - 1);
}
Map<String, int> memo = {};

int gridTraveler(int m, int n) {
  if (m == 0 || n == 0) {
    return 0;                      
  }
  if (m == 1 && n == 1) {
    return 1;                    
  }
  if (memo.containsKey('${m},${n}')) {
    return memo['${m},${n}'] as int;          
  }

  if (memo.containsKey('${n},${m}')) {
    return memo['${n},${m}'] as int;            
  }
  memo['${m},${n}'] = gridTraveler(m - 1, n) + gridTraveler(m, n - 1);  
    return memo['${m},${n}'] as int;                                   
}                                                                      
           
为什么时间复杂度是O(2^(m+n))?使用递归关系有什么解释吗

此外,还采用记忆法实现了网格移动器递归:

int gridTraveler(int m, int n) {
  if (m == 0 || n == 0) {
    return 0;
  }
  if (m == 1 || n == 1) {
    return 1;
  }
  return gridTraveler(m - 1, n) + gridTraveler(m, n - 1);
}
Map<String, int> memo = {};

int gridTraveler(int m, int n) {
  if (m == 0 || n == 0) {
    return 0;                      
  }
  if (m == 1 && n == 1) {
    return 1;                    
  }
  if (memo.containsKey('${m},${n}')) {
    return memo['${m},${n}'] as int;          
  }

  if (memo.containsKey('${n},${m}')) {
    return memo['${n},${m}'] as int;            
  }
  memo['${m},${n}'] = gridTraveler(m - 1, n) + gridTraveler(m, n - 1);  
    return memo['${m},${n}'] as int;                                   
}                                                                      
           
Map memo={};
int gridTraveler(int m,int n){
如果(m==0 | | n==0){
返回0;
}
如果(m==1&&n==1){
返回1;
}
if(memo.containsKey('${m},${n}')){
返回memo['${m},${n}']作为int;
}
if(memo.containsKey('${n},${m}')){
返回memo['${n},${m}']作为int;
}
备忘录['${m},${n}]=gridTraveler(m-1,n)+gridTraveler(m,n-1);
返回memo['${m},${n}']作为int;
}                                                                      

为什么时间复杂度是O(m*n)?使用递归关系有什么解释吗?

对于不使用记忆方法的网格遍历递归方法,如果我们绘制树,它将类似于

这里,对于每个节点或状态,将计算两个子节点/状态,直到它们到达基本情况。因此,对于N=m+N,将有2^N个节点或状态。所以时间复杂度是O(2^(N))或O(2^(N+m))

现在,如果我们看这棵树,我们正在计算先前计算的状态值,因此相同状态的值会计算很多次。使用记忆技术,如果我们计算一个状态,我们会保存它的值,如果我们达到之前计算的状态,我们会从DP表返回值。所以我们只计算一个状态一次,在DP表中可以有m*n个状态


因此,使用记忆方法时,时间复杂度为O(m*n)

这是一个很好的答案,但在无记忆递归的情况下,并非每个节点都有2个子节点——当n=1或m=1时,树的分支被切断。简化为每个节点都有2个子节点是合理的,这就给出了2^(m+n)的上界。如果你不简化,你会得到更精确的(m+n)选择n。你能详细说明m*n是什么吗?可能的总节点数是多少?因为当我计算gridtraveler(3,3)时,它有11个节点,而不是9个节点?除了基本情况,几乎有n*m个节点需要记忆。可能您正在多次计算相同的节点。假设,我们计算gridtraveler(2,2),它的值存储在DP表中。如果我们再次到达gridtraveler(2,2),我们将不再进一步计算,我们将从DP表返回值。还有n*m组合。用笔和纸来形象化。也不要把基础案例看作是计算节点。