返回

LeetCode 1. 两数之和:Swift 题解从入门到精通

闲谈

LeetCode 1. 两数之和:多种解法详解

介绍

LeetCode 1. 两数之和是 LeetCode 上一道经典的算法题,题目要求你找到一个整数数组中两个数字之和等于目标值的索引。这道题乍一看很简单,但其实有多种解法,每种解法都有其独特的优缺点。

暴力解法

最简单直观的解法是暴力解法,即枚举所有可能的数字对,并检查它们的和是否等于目标值。这种方法很容易理解和实现,但它的时间复杂度为 O(n^2),效率非常低。

func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
    for i in 0..<nums.count {
        for j in i+1..<nums.count {
            if nums[i] + nums[j] == target {
                return [i, j]
            }
        }
    }
    return []
}

哈希表解法

哈希表解法是一种更有效的方法。它的基本思想是将每个数字及其索引存储在一个哈希表中,然后对于每个数字,在哈希表中查找其补数(即 target - nums[i])。如果补数存在,则返回两个数字的索引。这种方法的时间复杂度为 O(n),效率要比暴力解法高很多。

func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
    var dict = [Int: Int]()
    for (i, num) in nums.enumerated() {
        let complement = target - num
        if let index = dict[complement] {
            return [index, i]
        }
        dict[num] = i
    }
    return []
}

双指针解法

双指针解法是另一种高效的解法。它的基本思想是使用两个指针,一个指向数组的开头,另一个指向数组的结尾。然后,比较这两个数字的和与目标值的差异。如果差异为 0,则返回两个数字的索引。如果差异大于 0,则将左指针向右移动。如果差异小于 0,则将右指针向左移动。这种方法的时间复杂度为 O(n),效率与哈希表解法相当。

func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
    var left = 0
    var right = nums.count - 1
    while left < right {
        let sum = nums[left] + nums[right]
        if sum == target {
            return [left, right]
        } else if sum < target {
            left += 1
        } else {
            right -= 1
        }
    }
    return []
}

总结

LeetCode 1. 两数之和是一道经典的算法题,有多种解法,每种解法都有其独特的优缺点。暴力解法简单易懂,但效率低下。哈希表解法和双指针解法效率更高,但实现起来也更加复杂。在实际应用中,应该根据具体情况选择合适的解法。

常见问题解答

  1. 为什么暴力解法的时间复杂度是 O(n^2)?
    因为暴力解法需要枚举所有可能的数字对,而数字对的数量为 n^2。

  2. 哈希表解法是如何工作的?
    哈希表解法通过将数字及其索引存储在哈希表中,可以快速查找一个数字的补数。

  3. 双指针解法是如何工作的?
    双指针解法使用两个指针,一个指向数组的开头,另一个指向数组的结尾。然后,比较这两个数字的和与目标值的差异,并相应地移动指针。

  4. 哪种解法最适合解决两数之和问题?
    在实际应用中,需要根据具体情况选择合适的解法。如果数组非常大,则哈希表解法或双指针解法效率更高。如果数组相对较小,则暴力解法也可以接受。

  5. 两数之和问题还有其他解决方法吗?
    是的,还有其他解决方法,例如使用排序树或二分查找。然而,这些方法的效率通常不如哈希表解法或双指针解法。