【问题标题】:Time Complexity Clarification On Backtracking Algorithm回溯算法的时间复杂度说明
【发布时间】:2018-05-06 20:30:45
【问题描述】:

我写了以下算法来解决一个经典的回溯问题:编写一个程序,它接受一个由 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 次(从 range(1, L + 1) 开始一次),导致 O( L^2)。如果我正在回答算法问题,甚至试图分析时间复杂度,说时间复杂度 O(N),因为时间复杂度随数组长度缩放似乎具有误导性,因为它没有考虑输入的重要性。

【问题讨论】:

    标签: python algorithm backtracking


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 2018-01-10
      • 1970-01-01
      相关资源
      最近更新 更多