【发布时间】:2012-02-09 18:45:57
【问题描述】:
我最近尝试在 Python 中解决一些任务,我发现解决方案似乎具有 O(n log n) 的复杂性,但我认为它对于某些输入来说效率非常低(例如第一个参数是0 和pairs 是很长的零列表)。
它还具有三个级别的for 循环。我相信它可以优化,但目前我无法对其进行更多优化,我可能只是缺少一些明显的东西;)
所以,基本上,问题如下:
给定整数列表 (
values),函数需要返回满足以下条件的索引对的数量:
- 让我们假设单个索引对是一个像
(index1, index2)这样的元组,- 那么
values[index1] == complementary_diff - values[index2]为真,示例: 如果将
[1, 3, -4, 0, -3, 5]之类的列表作为values和1作为complementary_diff,则该函数应返回4(这是以下索引对列表的长度:[(0, 3), (2, 5), (3, 0), (5, 2)])。
这是我目前所拥有的,它应该在大多数情况下都能完美运行,但是 - 正如我所说 - 在某些情况下它可能会运行得很慢,尽管它的复杂度接近 O(n log n) (看起来悲观复杂度是O(n^2))。
def complementary_pairs_number (complementary_diff, values):
value_key = {} # dictionary storing indexes indexed by values
for index, item in enumerate(values):
try:
value_key[item].append(index)
except (KeyError,): # the item has not been found in value_key's keys
value_key[item] = [index]
key_pairs = set() # key pairs are unique by nature
for pos_value in value_key: # iterate through keys of value_key dictionary
sym_value = complementary_diff - pos_value
if sym_value in value_key: # checks if the symmetric value has been found
for i1 in value_key[pos_value]: # iterate through pos_values' indexes
for i2 in value_key[sym_value]: # as above, through sym_values
# add indexes' pairs or ignore if already added to the set
key_pairs.add((i1, i2))
key_pairs.add((i2, i1))
return len(key_pairs)
对于给定的示例,它的行为如下:
>>> complementary_pairs_number(1, [1, 3, -4, 0, -3, 5])
4
如果您看到代码如何“扁平化”或“简化”,请告诉我。
我不确定仅检查 complementary_diff == 0 等是否是最好的方法 - 如果您认为是,请告诉我。
编辑:我已经更正了这个例子(谢谢,unutbu!)。
【问题讨论】:
-
如果有什么不清楚的地方或者你有什么问题,请问他们——也许我可以改进我的问题:)
-
我认为您示例中的
key_pairs是set([(3, 0), (0, 3), (5, 2), (2, 5)])(注意5,而不是4)。是吗? -
@unutbu:你说得对,谢谢!我已经编辑了问题。
标签: python algorithm loops nested complexity-theory