Day1:LeeCode Hot1-两数之和
大家好,今天开启 LeetCode Hot100 系列 的第一篇:两数之和。
两数之和作为LeetCode第一题、入门必刷题、面试高频手撕题,看似简单,却是算法入门的标杆题型。很多同学刷完只知道怎么写代码,却不懂为什么可以优化、时间复杂度差在哪里、面试怎么讲思路。
这道题也是典型的从暴力解题到最优解优化的经典案例,非常适合用来建立「算法优化思维」。
题目描述:
给定一个整数数组 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]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
题目核心关键点:
- 同一个元素不能重复使用(下标不能相同)
二、解法一:暴力枚举法(双循环)
2.1 解题思路
通过两层for循环遍历数组:
- 第二层循环:遍历 i 之后的所有数 nums[j]
优化小细节:第二层循环从 j = i + 1 开始,避免重复遍历(i=0,j=1 和 i=1,j=0 是同一组数据),同时保证同一个元素不重复使用。
public class TwoSum {
public int[] twoSum(int[] nums, int target) {
// 第一层循环:固定第一个元素
for (int i = 0; i < nums.length; i++) {
// 第二层循环:遍历后续元素,避免重复匹配
for (int j = i + 1; j < nums.length; j++) {
// 匹配目标值
if (nums[i] + nums[j] == target) {
return new int[]{i, j};
}
}
}
// 题目保证必有解,此处仅为语法兜底
return new int[]{};
}
}
- 时间复杂度:O(n²),最差情况下需要遍历所有两两组合,双层循环嵌套
2.4 优缺点总结
缺点:时间复杂度高,数组数据量大时会超时。当数组长度达到10⁴及以上,双层循环的计算量会急剧飙升,无法通过LeetCode严苛的时间限制。
三、解法二:哈希表法(最优解)
Java中的HashMap 查询效率为 O(1),我们可以借助哈希表将两数之和的时间复杂度从 O(n²) 优化至 O(n),这也是本题的标准答案、面试最优解。
核心公式:目标差值 = target - 当前遍历元素
- 遍历数组时,计算当前数值需要的 互补差值
核心逻辑:边遍历、边存储、边匹配,一次遍历即可完成解题。
import java.util.HashMap;
import java.util.Map;
public class TwoSum {
public int[] twoSum(int[] nums, int target) {
// key:数组数值,value:对应下标
Map<Integer, Integer> hashMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
// 计算需要寻找的互补数值
int complement = target - nums[i];
// 哈希表中存在互补值,匹配成功
if (hashMap.containsKey(complement)) {
// 返回历史数值下标、当前数值下标
return new int[]{hashMap.get(complement), i};
}
// 未匹配成功,存入当前数值和下标
hashMap.put(nums[i], i);
}
return new int[]{};
}
}
- 时间复杂度:O(n),仅需一次遍历数组,哈希表查询、插入操作均为 O(1)
3.4 核心优势
- 逻辑清晰,是面试中唯一推荐的写法
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|---|
| 暴力枚举法 | O(n²) | O(1) | 思路简单、无额外空间开销 | 效率极低、大数据量超时 | 极小数据量、算法入门练习 |
| 哈希表法 | O(n) | O(n) | 效率极致、适配大数据量 | 需要额外内存空间存储哈希表 | 刷题、面试、工程场景 |
五、面试高频提问与解答
Q1:为什么哈希表可以把时间复杂度从 O(n²) 降到 O(n)?
暴力法需要两层循环遍历所有组合,本质是通过遍历查询目标数值;而HashMap底层是哈希桶结构,基于哈希算法实现常数级查询,只需一次遍历数组,通过空间换时间的方式消除第二层循环,大幅提升效率。
Q2:为什么不会出现同一个元素重复匹配的情况?
代码逻辑是先查询、后存入。遍历当前元素时,哈希表中只存储了当前元素之前的所有数据,不会包含自身,因此不会出现同一个元素使用两次的情况,完美契合题目要求。
Q3:数组中有重复数值会影响结果吗?
不会。题目保证仅有一组唯一解,且后遍历的数值会覆盖哈希表中重复的key,但由于匹配优先于存入,不会影响正确结果的返回。
六、刷题总结
从「无脑暴力枚举」到「空间换时间哈希优化」,是所有算法刷题的核心成长路径。
后续我会持续更新 LeetCode Hot100 系列,每道题都包含「思路+代码+优化」,帮大家搞定算法!
浙公网安备 33010602011771号