返回

leetcode入门系列—01 挑战经典之两数之和

前端

揭秘两数之和:LeetCode 上一道经典编程难题

作为一名编程爱好者,LeetCode 绝对是你提升技能的宝贵资源。它提供了大量优质的编程难题,涵盖广泛的数据结构、算法和编程范例,非常适合磨练你的编码技巧和巩固基础。在本文中,我们将深入探讨 LeetCode 上最经典的题目之一:两数之和。

什么是两数之和问题?

两数之和问题要求你在一个整数数组中找到两数,使得它们的和等于一个给定的目标值。例如,对于数组 [2, 7, 11, 15] 和目标值 9,答案是索引为 0 和 1 的两数 [2, 7],因为它们的和为 9。

暴力法:逐个比较,穷举所有可能性

暴力法是最直接的解法,它遍历数组中的所有可能对,检查它们的和是否等于目标值。尽管它简单易懂,但其时间复杂度为 O(n^2),随着数组大小的增加,效率会急剧下降。

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

哈希表法:利用映射快速查找

哈希表法通过构建一个数字和索引的映射来优化暴力法。当遍历数组时,我们检查哈希表中是否存在与目标值之差的数字。如果存在,我们返回它们的索引。这种方法的时间复杂度为 O(n),因为我们只遍历数组一次。

def twoSum_hash_table(nums, target):
    hash_table = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in hash_table:
            return [hash_table[complement], i]
        hash_table[num] = i
    return None

双指针法:利用排序特性优化搜索

双指针法是一种巧妙的方法,它利用数组排序的特性。我们使用两个指针,一个指向数组的开头,另一个指向结尾。然后,我们检查指针所指数字的和。如果它等于目标值,我们就找到了答案。否则,我们根据和的大小调整指针的位置,直到找到答案或遍历完整个数组。这种方法的时间复杂度也是 O(n),因为它只遍历数组一次。

def twoSum_two_pointers(nums, target):
    left, right = 0, len(nums) - 1
    while left < right:
        sum = nums[left] + nums[right]
        if sum == target:
            return [left, right]
        elif sum < target:
            left += 1
        else:
            right -= 1
    return None

总结

两数之和问题有多种解法,每种解法都有其优点和缺点。暴力法简单易懂,但效率低。哈希表法通过利用映射优化暴力法,时间复杂度降为 O(n)。双指针法进一步利用数组排序特性,时间复杂度保持为 O(n)。在实际应用中,可以根据具体情况选择合适的方法来解决问题。

常见问题解答

  1. 暴力法是否可以在实际应用中使用?
    答:暴力法对于小规模数组是可行的,但对于大规模数组,其效率会急剧下降。

  2. 哈希表法在什么时候比双指针法更有优势?
    答:当数组中的数字范围有限时,哈希表法通常比双指针法更有效。

  3. 为什么双指针法要求数组必须排序?
    答:双指针法利用排序数组中数字的顺序关系来缩小搜索范围。

  4. 除了上述方法之外,还有其他解法吗?
    答:是的,还有一些其他解法,例如前缀和法和二分查找法。

  5. LeetCode 上的两数之和问题还有哪些变种?
    答:LeetCode 上还有两数之和 II(存在重复元素)、三数之和和四数之和等变种。