回溯算法

时间:2018-05-06 20:30:46

标签: python algorithm backtracking

我写了下面的算法来解决一个经典的回溯问题:编写一个带有n个整数数组的程序,其中A [i]表示你可以从索引i前进的最大值,并返回是否可以前进到从数组开始的最后一个索引。

换句话说,A中的第i个条目是我们可以从i前进的最大值。

例如, 如果A = [3,3,1,0,2,0,1],则可以达到最后一个索引。 如果A = [3,2,0,0,2,0,1],则不能。

我写了以下代码:

from collections import defaultdict 
def array_advance(lst):
  dict = defaultdict(lambda: 0)
  return advance(0, lst, dict)

def advance(start_idx, lst, memo):
  if start_idx >= len(lst): return False 
  if start_idx == len(lst) -1: return True 
  step_size = lst[start_idx]
  for i in range(1, step_size + 1):
    memo[step_size] |= advance(start_idx + step_size, lst, memo)
    if memo[step_size]:
      return True 
  return False

使用此代码,我知道只有N个函数调用。如果我们记忆,则访问每个索引并缓存函数(索引)输出。

但是,我无法理解时间复杂性。关于输入的大小,当然时间复杂度与O(N)成比例。但是,输入内容也是如此。如果每个元素是L,并且输入的大小是10L,则for循环将按O(L)缩放,运行L次(从范围(1,L + 1)开始一次),导致O( L ^ 2)。如果我回答算法问题,或者甚至试图分析时间复杂度,说时间复杂度O(N)因为时间复杂度与数组长度的关系似乎有误导性,因为它没有考虑到重要性输入。

1 个答案:

答案 0 :(得分:1)

假设步长从不超过数组,你可以说它是O(sum(A)),因为这是一个考虑数组元素的紧束缚。你也可以说它是O(N^2),因为那是最糟糕的情况。

你可以通过向后遍历数组来解决O(N)时间和O(1)空间中的问题,记录到目前为止找到的最小索引,这样你就可以到达终点。

def array_advance(a):
    i = len(a) - 1
    for j in range(i, -1, -1):
        if j + a[j] >= i: i = j
    return i == 0