[特殊字符] LeetCode 哈希表经典三题总结:1、49、128(思路 + 代码 + 模板)

在 LeetCode 的题目体系中,哈希表(Hash Table) 是最常见、最重要的数据结构之一。

它的核心优势是:

用空间换时间,将查找复杂度从 O(n) 降到 O(1)。

很多面试高频题都离不开哈希表的思想。

本篇博客将系统总结三道最经典的哈希表入门题:

  • 1. 两数之和(Two Sum)

  • 49. 字母异位词分组(Group Anagrams)

  • 128. 最长连续序列(Longest Consecutive Sequence)

并通过这三题掌握哈希表最核心的三种用法:

✅ 查补数

✅ 分组映射

✅ 连续序列判断



一、LeetCode 1:两数之和(Two Sum)

1. 两数之和 - 力扣(LeetCode)


1. 题目描述

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

示例

bash 复制代码
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:nums[0] + nums[1] = 2 + 7 = 9

2. 暴力思路(不可取)

最直观的方法是双重循环:

cpp 复制代码
for i:
    for j:
        if nums[i] + nums[j] == target

时间复杂度:

bash 复制代码
O(n²)

当 n 达到 10⁵ 时直接超时。


3. 哈希表优化思路

核心思想:查找补数

遍历数组时:

  • 当前数字为 x

  • 需要另一个数字 need = target - x

如果之前出现过 need,说明答案已找到。

因此我们使用哈希表:

  • key:数字

  • value:数字出现的位置


4. C++代码实现

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> mp;

        for (int i = 0; i < nums.size(); i++) {
            int need = target - nums[i];

            if (mp.count(need)) {
                return {mp[need], i};
            }

            mp[nums[i]] = i;
        }

        return {};
    }
};

5. 复杂度分析

|------|--------|
| 操作 | 复杂度 |
| 遍历数组 | O(n) |
| 哈希查找 | O(1) |
| 总复杂度 | ✅ O(n) |



二、LeetCode 49:字母异位词分组(Group Anagrams)


1. 题目描述

给定字符串数组 strs,请你将所有 字母异位词 分组。

字母异位词:

  • 字母相同

  • 顺序不同

示例

复制代码
bash 复制代码
输入:["eat","tea","tan","ate","nat","bat"]

输出:
[
  ["eat","tea","ate"],
  ["tan","nat"],
  ["bat"]
]

2. 哈希表的核心:分类映射

异位词的本质

两个字符串是异位词:

排序后一定完全相同。

例如:

|------|-----|
| 原字符串 | 排序后 |
| eat | aet |
| tea | aet |
| ate | aet |

因此可以用:

  • key:排序后的字符串

  • value:所有属于该 key 的字符串集合


3. 解题步骤

  1. 遍历字符串数组

  2. 对每个字符串排序得到 key

  3. 放入哈希表中分类

  4. 最后输出所有组


4. C++代码实现

cpp 复制代码
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> mp;

        for (auto& s : strs) {
            string key = s;
            sort(key.begin(), key.end());

            mp[key].push_back(s);
        }

        vector<vector<string>> result;
        for (auto& p : mp) {
            result.push_back(p.second);
        }

        return result;
    }
};

5. 复杂度分析

设:

  • n 为字符串数量

  • k 为字符串平均长度

排序复杂度:

bash 复制代码
O(k log k)

总复杂度:

bash 复制代码
O(n * k log k)


三、LeetCode 128:最长连续序列(Longest Consecutive Sequence)


1. 题目描述

给定一个未排序整数数组 nums,找出数字连续的最长序列长度。

要求算法复杂度必须为:

bash 复制代码
O(n)

示例

bash 复制代码
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长连续序列是 [1,2,3,4]

2. 核心难点

排序可以解决:

cpp 复制代码
sort(nums)

但复杂度:

cpp 复制代码
O(n log n)

题目要求必须 O(n)。


3. 哈希集合解法:从起点扩展

核心思想

如果数字 x 是一个连续序列的起点:

bash 复制代码
x - 1 不存在

例如:

序列 [1,2,3,4]

起点只有 1,因为:

  • 1-1 = 0 不存在

所以:

  • unordered_set 存所有数字

  • 只从起点开始扩展

  • 每个数字最多访问一次


4. C++代码实现

cpp 复制代码
class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> st(nums.begin(), nums.end());

        int longest = 0;

        for (int x : st) {
            // 只有当 x 是起点才扩展
            if (!st.count(x - 1)) {
                int cur = x;
                int len = 1;

                while (st.count(cur + 1)) {
                    cur++;
                    len++;
                }

                longest = max(longest, len);
            }
        }

        return longest;
    }
};

5. 复杂度分析

|------|--------|
| 操作 | 复杂度 |
| 建集合 | O(n) |
| 扩展遍历 | O(n) |
| 总复杂度 | ✅ O(n) |



四、三题核心套路总结


|-----|---------------------|--------------------------------|------|
| 题号 | 题目 | 哈希结构 | 核心思想 |
| 1 | Two Sum | unordered_map | 查补数 |
| 49 | Group Anagrams | unordered_map<string,vector> | 分类映射 |
| 128 | Longest Consecutive | unordered_set | 起点扩展 |


五、哈希表题目三大模板


模板 1:查找补数

cpp 复制代码
need = target - x;
if (mp.count(need)) return ans;

模板 2:分类映射

cpp 复制代码
key = transform(x);
mp[key].push_back(x);

模板 3:存在性判断 + 起点扩展

cpp 复制代码
if (!st.count(x-1)) {
    while(st.count(x+1)) ...
}

六、总结

通过这三道经典题,你应该掌握哈希表在 LeetCode 中最常见的三种用途:

✅ 快速查找

✅ 分类分组

✅ 判断连续关系

哈希表题目看似简单,但却是面试必考的基础能力。


📌 下一步推荐练习(哈希专题)

如果你想继续刷哈希题,可以按顺序练:

  • 217 存在重复元素

  • 242 有效的字母异位词

  • 560 和为 K 的子数组

  • 347 前 K 个高频元素

  • 15 三数之和(哈希 + 双指针)


相关推荐
只是懒得想了5 小时前
C++实现密码破解工具:从MD5暴力破解到现代哈希安全实践
c++·算法·安全·哈希算法
码农水水5 小时前
得物Java面试被问:消息队列的死信队列和重试机制
java·开发语言·jvm·数据结构·机器学习·面试·职场和发展
m0_736919105 小时前
模板编译期图算法
开发语言·c++·算法
dyyx1115 小时前
基于C++的操作系统开发
开发语言·c++·算法
m0_736919105 小时前
C++安全编程指南
开发语言·c++·算法
蜡笔小马5 小时前
11.空间索引的艺术:Boost.Geometry R树实战解析
算法·r-tree
-Try hard-5 小时前
数据结构:链表常见的操作方法!!
数据结构·算法·链表·vim
2301_790300966 小时前
C++符号混淆技术
开发语言·c++·算法
我是咸鱼不闲呀6 小时前
力扣Hot100系列16(Java)——[堆]总结()
java·算法·leetcode
嵌入小生0076 小时前
单向链表的常用操作方法---嵌入式入门---Linux
linux·开发语言·数据结构·算法·链表·嵌入式