力扣HOT100刷题记录-哈希-题解-1.两数之和

9 阅读3分钟

两数之和

题目描述

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

示例:

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

解题思路分析

方法一:暴力解法(容易想到)

两层for循环遍历所有可能的组合,时间复杂度O(n²),空间复杂度O(1)

#include<iostream>
#include<vector>

using namespace std;

int main(){
    // 输入:nums = [2,7,11,15], target = 9
    vector<int> nums = {2,7,11,15};
    int target = 9;
    
    for(int i=0;i<nums.size();i++){//遍历数组
        int x=target-nums[i];//获取差值
        for(int j=i+1;j<nums.size();j++){
            if(nums[j]==x){
                cout<<j<<" "<<i;
            }
        }
    }
}

方法二:哈希表优化

通过一次遍历,在遍历过程中使用哈希表记录已访问过的元素及其索引,从而将查找时间复杂度从O(n)降低到O(1)。

#include<iostream>
#include<vector>
#include<unordered_map>

using namespace std;

int main(){
    // 输入:nums = [2,7,11,15], target = 9
    vector<int> nums = {2,7,11,15};
    int target = 9;
    unordered_map<int,int> hash;//创建一个哈希表
    
    for(int i=0;i<nums.size();i++){//遍历数组
        int x=target-nums[i];//获取差值
        if(hash.find(x) != hash.end()){//判断差值是否存在于哈希表中
            cout<<hash[x]<<" "<<i;//输出索引
        }
        hash[nums[i]] = i;//将当前元素及其索引存入哈希表
    }
}

核心思想与关键问题解答

1. 为什么会想到用哈希表?

我的思考过程:

当我分析这个问题时,最直观的想法是使用双重循环暴力求解,时间复杂度为O(n²)。但仔细思考后发现:

  • 对于每个元素nums[i],我需要快速找到是否存在另一个元素等于target - nums[i]
  • 如果能在O(1)时间内完成这个查找操作,整体时间复杂度就能降到O(n)
  • 哈希表正好提供了这样的能力——平均情况下查找、插入、删除都是O(1)的时间复杂度
  • 这样就能避免重复计算,大大提高效率

2. 哈希表为什么用unordered_map?

选择理由:

  • 在C++中,unordered_map是基于哈希表实现的,查询和增删效率都是最优的,平均时间复杂度为O(1)
  • 如果​不需要有序​,优先使用 unordered_set(集合)或 unordered_map(键值对),因为它们查询、插入、删除最快
  • 如果​需要集合有序​,使用 set
  • 如果​不仅有序还要允许重复数据​,使用 multiset

3. 哈希法的适用场景

当我们遇到要快速判断一个元素是否出现在集合里的时候,就要考虑哈希法。

4. 算法流程详解

  1. 初始化一个空的unordered_map

  2. 遍历每个元素nums[i]:

    • 计算差值x = target - nums[i]
    • 检查哈希表中是否存在key为x的元素
    • 如果存在,返回hash[x]和i
    • 如果不存在,将当前元素nums[i]及其索引i存入哈希表
  3. 由于题目保证有且只有一个答案,循环结束后一定能找到解

  4. 模拟执行过程(nums = [2, 7, 11, 15], target = 9)

我们用一个表格来跟踪每一步:

步骤inums[i]complement = 9 - nums[i]哈希表当前状态(key: value = 值: 下标)是否找到?说明
初始---{}-哈希表为空
1027{} → 存入 {2: 0}7 不在表中,存入当前元素
2172{2: 0} → 找到 2!2 在表中,下标是 0,当前下标是 1 → 返回 [0, 1]