【发布时间】:2014-10-06 12:15:58
【问题描述】:
想象一下,你有两个麻袋(A 和 B),里面分别装有 N 和 M 球。每个球都有一个已知的数值(利润)。您被要求提取(有替换)具有最大总利润的一对球(由所选球的乘积得出)。
最佳提取是显而易见的:从A 和B 中选择价值最高的球。
当您被要求给出第二或第 k 个最佳选择时,问题就来了。按照前面的方法,您应该从A 和B 中选择价值最高的球,而无需重复选择。
这可以很笨拙地解决计算每个可能选择的值,对其进行排序和排序(python中的示例):
def solution(A,B,K):
if K < 1:
return 0
pool = []
for a in A:
for b in B:
pool.append(a*b)
pool.sort(reverse=True)
if K>len(pool):
return 0
return pool[K-1]
这可行,但它最差的时间复杂度是O(N*M*Log(M*M)),我敢打赌会有更好的解决方案。
我基于一个表找到了一个解决方案,其中A 和B 元素从高值到低值排序,并且这些值中的每一个都与一个索引相关联,该索引表示要从另一列测试的下一个值。最初,此表如下所示:
A 中的第一个元素是 25,它必须针对 20 进行测试 (index 2 select from b = 0),因此 25*20=500 是第一个最佳选择,并且在增加要检查的索引后,表会发生变化到:
使用这些索引,我们可以快速获得最佳候选者:
25 * 20 = 500 #first from A and second from B
20 * 20 = 400 #second from A and first from B
我尝试编写此解决方案:
def solution(A,B,K):
if K < 1:
return 0
sa = sorted(A,reverse=true)
sb = sorted(B,reverse=true)
for k in xrange(K):
i = xfrom
j = yfrom
if i >= n and j >= n:
ret = 0
break
best = None
while i < n and j < n:
selected = False
#From left
nexti = i
nextj = sa[i][1]
a = sa[nexti][0]
b = sb[nextj][0]
if best is None or best[2]<a*b:
selected = True
best = [nexti,nextj,a*b,'l']
#From right
nexti = sb[j][1]
nextj = j
a = sa[nexti][0]
b = sb[nextj][0]
if best is None or best[2]<a*b:
selected = True
best = [nexti,nextj,a*b,'r']
#Keep looking?
if not selected or abs(best[0]-best[1])<2:
break
i = min(best[:2])+1
j = i
print("Continue with: ", best, selected,i,j)
#go,go,go
print(best)
if best[3] == 'l':
dx[best[0]][1] = best[1]+1
dy[best[1]][1] += 1
else:
dx[best[0]][1] += 1
dy[best[1]][1] = best[0]+1
if dx[best[0]][1]>= n:
xfrom = best[0]+1
if dy[best[1]][1]>= n:
yfrom = best[1]+1
ret = best[2]
return ret
但它不适用于在线 Codility 评委(我是否提到这是解决已经过期的 Codility 挑战的部分?Sillicium 2014)
我的问题是:
- 第二种方法是未完成的好解决方案吗?如果是这样的话,有什么线索可以说明我可能遗漏了什么吗?
- 您知道解决此问题的更好方法吗?
【问题讨论】:
-
你读过这篇文章了吗:"How to find pair with kth largest sum?"。我认为它回答了您的第二个问题。
-
问题陈述有点不清楚。你能澄清你所说的第k个选择是什么意思吗?由于提取是有放回的,我们可以继续提取相同的最大值球。
-
@user1990169 认为它不是第 k 个选择,而是第 k 个最佳选择
-
好的,那么你想要第 k 个最大的对积吗?
-
取对数,然后在链接的帖子中应用解决方案。
标签: python performance algorithm math