【发布时间】:2015-01-31 15:11:36
【问题描述】:
这是一个典型的面试问题。给定一个既包含正元素又包含负元素但不包含 0 的数组,找到总和等于 0 的最大子数组。我试图解决这个问题。这就是我想出的。
def sub_array_sum(array,k=0):
start_index = -1
hash_sum = {}
current_sum = 0
keys = set()
best_index_hash = {}
for i in array:
start_index += 1
current_sum += i
if current_sum in hash_sum:
hash_sum[current_sum].append(start_index)
keys.add(current_sum)
else:
if current_sum == 0:
best_index_hash[start_index] = [(0,start_index)]
else:
hash_sum[current_sum] = [start_index]
if keys:
for k_1 in keys:
best_start = hash_sum.get(k_1)[0]
best_end_list = hash_sum.get(k_1)[1:]
for best_end in best_end_list:
if abs(best_start-best_end) in best_index_hash:
best_index_hash[abs(best_start-best_end)].append((best_start+1,best_end))
else:
best_index_hash[abs(best_start-best_end)] = [(best_start+1,best_end)]
if best_index_hash:
(bs,be) = best_index_hash[max(best_index_hash.keys(),key=int)].pop()
return array[bs:be+1]
else:
print "No sub array with sum equal to 0"
def Main():
a = [6,-2,8,5,4,-9,8,-2,1,2]
b = [-8,8]
c = [-7,8,-1]
d = [2200,300,-6,6,5,-9]
e = [-9,9,-6,-3]
print sub_array_sum(a)
print sub_array_sum(b)
print sub_array_sum(c)
print sub_array_sum(d)
print sub_array_sum(e)
if __name__ == '__main__':
Main()
我不确定这是否会满足所有边缘情况。如果有人可以对此发表评论,那就太好了另外我想将其扩展到等于任何 K 而不仅仅是 0 的总和。我应该怎么做。任何进一步优化这一点的指针也很有帮助。
【问题讨论】:
-
这个问题可能会在 codereview.stackexchange.com 而不是 stackoverflow 中得到好评
-
这不是subset sum problem吗?这是一个 NP 完全问题,所以我不希望有人找到有效的算法来解决它。
-
@Bakuriu 不,子数组
!=子序列。这个问题是关于一个子数组(连续元素),这使它更容易。 -
如果您还可以向我们提供您正在实施的算法的自然语言概述,将会很有帮助:它为什么有效,什么是循环不变量,什么是时间/空间复杂性?
-
克里斯,OP 似乎正在使用逻辑,为
a[1...n], sum(i,j) = sum(0,j) - sum(0,i)。但是代码确实被多余的数据结构所累。