leetcode001 两数之和

问题描述:两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且不能重复使用相同的元素。可以按任意顺序返回答案。


示例

示例 1

  • 输入 : nums = [2,7,11,15], target = 9
  • 输出 : [0,1]
  • 解释 : 因为 nums[0] + nums[1] == 9,返回 [0, 1]

示例 2

  • 输入 : nums = [3,2,4], target = 6
  • 输出 : [1,2]
  • 解释 : nums[1] + nums[2] == 6,返回 [1, 2]

示例 3

  • 输入 : nums = [3,3], target = 6
  • 输出 : [0,1]
  • 解释 : nums[0] + nums[1] == 6,返回 [0, 1]

约束条件

  • 2 <= nums.length <= 10⁴
  • -10⁹ <= nums[i] <= 10⁹
  • -10⁹ <= target <= 10⁹
  • 只会存在一个有效答案

进阶要求

你能想出一个时间复杂度小于 O(n²) 的算法吗?


解法思路

1. 暴力枚举(Brute Force)

  • 时间复杂度: O(n²)
  • 空间复杂度: O(1)
  • 思路
    • 使用双重循环,遍历所有可能的两个数的组合。
    • 检查它们的和是否等于 target,如果找到则返回下标。

2. 哈希表优化(Optimal Solution)

  • 时间复杂度: O(n)
  • 空间复杂度: O(n)
  • 思路
    • 使用哈希表(如 unordered_map)存储 {value: index}
    • 遍历数组,对于每个元素 nums[i],计算 complement = target - nums[i]
    • 检查 complement 是否在哈希表中:
      • 如果存在,直接返回 {map[complement], i}
      • 否则,将当前 nums[i] 存入哈希表。

代码实现

暴力枚举(C++)

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        // 暴力枚举
        for(int i = 0; i < nums.size(); i++){  
            for(int j = i + 1; j < nums.size(); j++){  
                if(nums[i] + nums[j] == target){ 
                    return {i, j};  
                }
            }
        }
        return {};  // 理论上题目保证有解,但最好添加默认返回值
    }
};

哈希表优化(C++)

cpp 复制代码

总结

方法 时间复杂度 空间复杂度 适用情况
暴力枚举 O(n²) O(1) 数据量较小
哈希表优化 O(n) O(n) 数据量较大

推荐使用哈希表优化解法,因为它显著降低了时间复杂度,适用于较大的输入规模。