最近我遇到了一个似乎很有趣的游戏,它建议在大型数据集上同时实现两指针和前缀和技术。这是任务本身:
想象有一个长度为k的数组v ,其中k (k<=10**5) 表示由两个数字组成的条目数量:A(所谓的堆)和N(数量),例如:
k = 3
v = [[2, 2], [3, 2], [2, 1]]
A ( v[i][0]
) 是值,N ( v[i][1]
) 是给出该值的次数。换句话说,N是A的频率。
现在,我们要做的是选择最小的 A,从列表的两端开始,从当前位置减去它,然后将它添加到后面的位置。然后我们继续这样做,直到中间只剩下两个或一个etries。换句话说,每一步我们选择最小的一堆,然后从两端减去它,直到剩下一两堆。
答案应该包括两行:第一行包含“1”或“2”,具体取决于剩余的桩数,第二行是结果本身。
为简化起见,我们可以将堆表示为如下所示的普通列表:
v = [2, 2, 3, 3, 2]
我们从左端和右端(2)中选择最小值,减去它并添加到下一个值:
v = [0, 4, 3, 5, 0]
4 和 5 的最小值是 4,所以我们减去 4 得到两堆。
v = [0, 0, 11, 1, 0]
输出是:
2
11 1
我的代码是:
k = int(input())
a = []
for _ in range(k):
A, N = map(int, input().split())
x = [A] * N
a += x
l = 0
r = len(a)-1
while r - l > 1:
s = min(a[l], a[r])
a[l] -= s
a[r] -= s
a[l+1] += s
a[r-1] += s
if a[l] == 0:
l += 1
if a[r] == 0:
r -= 1
if a[r] == 0 or a[r]==a[l]:
print(1)
print(a[l])
else:
print(2)
print(a[l], a[r])
该解决方案在k = 10**5时未能达到时间限制(2 秒),因为它需要将数组转换为普通列表,并且几乎不使用前缀和。我确信有一个更快的解决方案,它带有前缀和、附加变量和存储一个给定的数组。对于如何加快此代码的任何建议,我将不胜感激。
为防止任何与语言相关的评论:该游戏适用于任何编程语言,因此时间限制不是专门针对 python 的问题。