【问题标题】:Adding duplicate keys to Python dictionary ("Two Sum" Problem)向 Python 字典添加重复键(“Two Sum”问题)
【发布时间】:2019-02-25 05:24:55
【问题描述】:

我一直在尝试将重复键添加到我的 python 字典(表)中,以解决“两个总和”问题。

给定一个整数数组,返回两个数字的索引,使它们相加为特定目标。

我现在已经意识到这是不可能做到的,并且很感激任何关于如何在没有蛮力的情况下解决这个问题的想法或建议。请记住,我这周开始尝试学习 Python。所以我很抱歉有一个简单的解决方案

numbers = [0, 0, 0, 0, 0, 0, 0]  # initial list
target = 6  # The sum of two numbers within list

# Make list into dictionary where the given values are used as keys and 
actual values are indices
table = {valueKey: index for index, valueKey in enumerate(numbers)}

print(table)

>>> {0: 6}

【问题讨论】:

  • 欢迎来到stackoverflow!您的问题可能已经在这里有了答案:stackoverflow.com/questions/10664856
  • 你可以使用元组列表(valueKey, index)
  • 为什么需要添加重复键?
  • @khachik 好吧,我对重复键的推理是我会将值存储为键,将索引存储为实际值。然后我可以得到(目标 - 当前迭代)并查找结果。我现在知道这是不可能的,哈哈

标签: python python-3.x dictionary duplicates


【解决方案1】:

您根本不需要存储索引,因为两个总和问题与 数字所在的位置无关,只需找到它们即可。这可以通过以下方式完成:

target = 6
numbers = [1, 5, 11, -5, 2, 4, 6, 7, 21]
hashTable = {}
results = []
for n in numbers:
    if ((target - n) in hashTable and hashTable[target - n] == None):
        hashTable[target - n] = n
    else:
        hashTable[n] = None

results = [[k, v] for k, v in hashTable.items() if v != None]
print(results)

如果您想要数字索引,可以添加第二个字典indices

indices = {}
for i, n in enumerate(numbers):
    if ((target - n) in hashTable and hashTable[target - n] == None):
        hashTable[target - n] = n
    else:
        hashTable[n] = None
    indices[n] = i

results = [[indices[k], indices[v]] for k, v in hashTable.items() if v != None]
print(results)

请注意,要使这两种解决方案都能正常工作,您需要保证每个元素在列表中只出现一次。否则,您的总和将是模棱两可的。您可以修改 indices 以存储出现特定值的索引列表,这将解决该问题。

【讨论】:

  • 我需要返回两个数字的索引而不是数字本身。你的最后一行返回了一个错误,但我明白你在做什么。谢谢!
  • 啊,在这种情况下,我建议使用类或元组。
【解决方案2】:

不确定您需要 dup 键的具体用途,但您可以使用值列表:

import collections

table = collections.defaultdict(list)

for i, value in enumerate(numbers):
    table[value].append(i)

diffs = enumerate(target - number for number in numbers)

for i, diff in diffs:
    if diff in table:
        indices = table[diff]
        indices.remove(i)
        if indices:
            print i, indices

我相信这个任务有更好的解决方案,很高兴看到其他答案。

【讨论】:

    【解决方案3】:

    我不明白你为什么需要一个字典,除非你有多个目标。我会改用set

    numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    target = 9
    answer = set()
    for i, iNumber in enumerate(numbers):
        for j, jNumber in enumerate(numbers):
            if i == j:
                continue
            mySum = iNumber + jNumber
            if (mySum == target):
                answer.add((i,j))
    

    【讨论】:

    • 这就是 OP 所说的“蛮力”并试图避免,它是 n^2。
    • 嗯...是的,我知道它可以更简洁和“pythonically”表达,@khachik,但我看不出如何加快计算时间,没有任何限制输入数组。你能想出办法吗?
    • 我在回答中做了
    • 这与“pythonical”或其他东西无关,它与运行时复杂性有关。
    【解决方案4】:

    我会对数组进行排序,进行某种二进制搜索来搜索目标的索引(或直接次要索引),并在较小的索引和使用二进制搜索找到的索引之间的索引中查找“二和”。

    例如: 数组 = [5,1,8,13,2,4,10,22] 目标 = 6

    sorted_array = [1,2,4,5,8,10,13,22] binary_search_index = 4(数字 5)

    所以知道您将数组缩减为:[1,2,4,5],您可以在那里查看“两个总和”,可能使用 de min 和 max 索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-06
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多