查找数组中两个数字的总和是否等于k

时间:2018-02-21 11:24:33

标签: java python algorithm hashmap hashtable

我正在努力解决:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

这是我的解决方案:

def twoSum(nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """

        hash_table = {}
        k = target

        for i, x in enumerate(nums):
            if x not in hash_table:
                hash_table[x] = i

        for x in nums:
            if k-x in hash_table:
                if hash_table[k-x]!= hash_table[x]:
                    return [hash_table[x], hash_table[k-x]] 

现在解决方案不正确,因为它失败了像[3,3],6这样的测试用例。现在两个3都作为预期的一个条目存储在哈希表中,因此哈希表中只记录了一个索引3,我的解决方案不起作用。

所以,我认为解决方案可能不适用于哈希表。但正确的解决方案是:

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        map.put(nums[i], i);
    }
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement) && map.get(complement) != i) {
            return new int[] { i, map.get(complement) };
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

现在,这在Java中基本上是相同的解决方案,并且它被称为正确的解决方案。

所以,我的问题是:

  1. 如何在Python中更改我的解决方案才能正常工作而不会使测试用例失败?
  2. Java解决方案有何不同,其哈希表是否还有其他行为?
  3. 感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

Java解决方案有一个检查,它负责两个相同的元素:

if (map.containsKey(complement) && map.get(complement) != i)

此条件的第一部分 - map.containsKey(complement) - 表示complement中存在数字Map,而第二部分 - map.get(complement) != i) - 表示该指数存储在地图中的complement与索引i不同。这意味着如果complement == nums[i],输入数组中有两个相同的数字。

我不了解Python,但看起来您的代码失败了,因为

if hash_table[k-x]!= hash_table[x]

k-x == x时始终返回false。您需要将hash_table[k-x]与输入数组的当前索引进行比较。

基于你的第一个Python循环,我假设第二个循环应该如下所示:

    for i, x in enumerate(nums):
        if k-x in hash_table:
            if hash_table[k-x]!= i:
                return [i, hash_table[k-x]] 

答案 1 :(得分:1)

为什么不用简单的东西:

def twoSum(nums, target):
    for i, num1 in enumerate(nums):
        for j, num2 in enumerate(nums):
            if num1 + num2 == target and i != j:
                return [i, j]
    return [-1, -1] # or whaterver you want to say "no solution found"

这会产生:

print twoSum([2, 7, 11, 15], 9)   # =>[0, 1] 2+7
print twoSum([2, 7, 11, 15], 22)  # =>[1, 3] 7+15
print twoSum([2, 7, 11, 15], 23)  # => [-1, -1]  no solution

答案 2 :(得分:1)

除了哈希表解决方案,您可以

  • 对数组进行排序(时间O(N Log N)),
  • 维护两个索引ij,使num[i] + num[j] <= sum < num[i] + num[j+1];每次增加i时,都会将j减少0或更多以进行调整。 i0开始,j从最后开始。

更糟糕的是,您增加i N次,并减少j N次,共计O(N)次操作。如果是平等的,你就完成了。

这可以就地完成。