您的方法存在两个问题:
-
这个问题可以在线性时间内解决,而不是递归,使用简单的for循环。
-
我们可以使用模运算规则来保持数字始终在
[0, 169)
.
解决第一个问题
我们可以在这里使用记忆。假设我们想找到
arr[100]
。我们需要什么信息才能找到这个?
我们有一个公式:
arr[i] = arr[i - 3] + arr[i - 2] * arr[i - 1]
因此,我们将
arr[100] = arr[97] + arr[98] * arr[99]
.
考虑以下场景:我们有
arr[0]
,
arr[1]
,
arr[2]
.如果我们计算并存储
arr[3]
?如果储存后
arr[3]
,我们计算
arr[4]
? ...?如果储存后
arr[99]
,我们计算
arr[100]
?
我们很容易看出
arr[100]
可以在恒定的时间内计算,正如我们已经拥有的那样
arr[97]
,
arr[98]
和
arr[99]
与我们一起存储。
您可以在此处看到此方法的另一个示例:
nth Fibonacci number in linear time
.
解决第二个问题
进入第二个问题,该问题可以使用模运算规则来求解。以下是我们需要的规则:
(a + b) % n = ((a % n) + (b % n)) % n
(a * b) % n = ((a % n) * (b % n)) % n
因为我们只需要
arr[249] % 169
,我们可以假设
n=169
我们的问题归结为
arr[i] % n
为所有人
i
从…起
0
到
249
因此,我们可以将方程转换为:
Let b[i] = arr[i] % n. We need b[249].
b[i]
= arr[i] % n
= (arr[i - 3] + arr[i - 2] * arr[i - 1]) % n
= ((arr[i - 3] % n) + (arr[i - 2] * arr[i - 1]) % n) % n
= (b[i - 3] + ((arr[i - 2] % n) * (arr[i - 1] % n)) % n) % n
= (b[i - 3] + (b[i - 2] * b[i - 1]) % n) % n.
因此,与其返回
arr[249]%169
,我们只是简单地返回
b[249]
.
伪代码
以下是相同的伪代码:
mod = 169
b = [0,0,0,...] # Size of b is 250
b[0] = 1
b[1] = 2
b[2] = 3
for i = 3 to 249 (included):
b[i] = (b[i - 3] + (b[i - 2] * b[i - 1]) % mod) % mod
print b[249]
这应该会让一切变得清楚。