【发布时间】: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