返回

掌握两数之和的正确姿势,轻松称霸算法题!

人工智能

两数之和题意

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出两个数字,使得它们相加之和等于 target。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

算法实现

针对两数之和的问题,我们可以使用暴力破解法或哈希表法来解决。

暴力破解法

暴力破解法是最简单直接的解法。我们可以使用两个嵌套的循环来遍历整个数组,并检查每个元素是否与其他元素相加等于 target。如果找到一对满足条件的元素,则返回它们的索引。

def twoSum(nums, target):
    """
    :type nums: List[int]
    :type target: int
    :rtype: List[int]
    """
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):
            if nums[i] + nums[j] == target:
                return [i, j]

哈希表法

哈希表法是一种更有效率的解法。我们可以先将数组中的元素和它们的索引存储到一个哈希表中。然后,我们可以遍历整个数组,并检查每个元素的补数是否在哈希表中。如果找到一对满足条件的元素,则返回它们的索引。

def twoSum(nums, target):
    """
    :type nums: List[int]
    :type target: int
    :rtype: List[int]
    """
    hashtable = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in hashtable:
            return [hashtable[complement], i]
        hashtable[num] = i

算法优化

为了进一步优化算法,我们可以对哈希表法进行一些改进。

1. 预处理数组

我们可以先对数组进行排序,然后再将数组中的元素和它们的索引存储到哈希表中。这样,我们就可以使用二分查找法来查找每个元素的补数。

def twoSum(nums, target):
    """
    :type nums: List[int]
    :type target: int
    :rtype: List[int]
    """
    nums.sort()
    hashtable = {}
    for i, num in enumerate(nums):
        complement = target - num
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == complement:
                return [i, mid]
            elif nums[mid] < complement:
                left = mid + 1
            else:
                right = mid - 1
        hashtable[num] = i

2. 使用位运算

如果数组中的元素都是非负整数,那么我们可以使用位运算来优化哈希表法。我们可以将每个元素的二进制表示作为哈希表中的键,并将元素的索引作为哈希表中的值。这样,我们就可以使用位运算来快速查找每个元素的补数。

def twoSum(nums, target):
    """
    :type nums: List[int]
    :type target: int
    :rtype: List[int]
    """
    hashtable = {}
    for i, num in enumerate(nums):
        complement = target - num
        bitmask = 1 << num
        if bitmask in hashtable:
            return [hashtable[bitmask], i]
        hashtable[bitmask] = i

实例

让我们来看一个具体的例子。给定数组 nums = [2, 7, 11, 15] 和目标值 target = 9,我们该如何找到两数之和?

暴力破解法

for i in range(len(nums)):
    for j in range(i + 1, len(nums)):
        if nums[i] + nums[j] == target:
            return [i, j]
[0, 1]

哈希表法

hashtable = {}
for i, num in enumerate(nums):
    complement = target - num
    if complement in hashtable:
        return [hashtable[complement], i]
    hashtable[num] = i
[0, 1]

优化后的哈希表法

nums.sort()
hashtable = {}
for i, num in enumerate(nums):
    complement = target - num
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] == complement:
            return [i, mid]
        elif nums[mid] < complement:
            left = mid + 1
        else:
            right = mid - 1
    hashtable[num] = i
[0, 1]

总结

两数之和是算法题中最经典的问题之一。通过本文的讲解,相信您已经掌握了两数之和的正确姿势。在以后的算法题中,您可以灵活运用这些技巧来解决问题。

如果您对本文有任何疑问,欢迎在评论区留言。