题目来源:LeetCode1:两数之和
问题抽象: 给定一个整数数组 nums 和一个整数目标值 target,要求在数组中找出两个不同的元素,使得它们的和等于 target,并返回这两个元素的数组下标。核心需求如下:
- 唯一解存在性:假设输入数据中恰好存在一个有效解,且同一元素不可重复使用。
- 索引定位:需返回两个元素在数组中的索引值(通常以整数数组形式)。
- 无序性约束:数组元素顺序任意,解对应的索引顺序无要求(如返回
[i, j]或[j, i]均可)。 - 高效查询:需避免暴力穷举,设计高效的查找策略(通常要求时间复杂度优于 O(n²))。
输入:整数数组 nums、整数 target
输出:包含两个索引值的数组(任意顺序)
解题思路
本题目要求在整数数组 nums 中找到两个数,使它们的和等于目标值 target,并返回这两个数的下标。核心思路是利用哈希表实现高效的补数查找:
-
问题分析:
暴力解法需要两层循环(时间复杂度 O(n²))。优化思路是空间换时间:通过哈希表存储已遍历元素的值与下标,实现 O(1) 复杂度的补数查找。 -
关键步骤:
- 补数计算:对于当前元素
nums[i],计算补数complement = target - nums[i]。 - 哈希表查询:检查补数是否在哈希表中:
- 若存在,直接返回
[补数的下标, 当前下标 i]。 - 若不存在,将
nums[i]及其下标存入哈希表,供后续查询使用。
- 若存在,直接返回
- 提前终止:题目保证有解,找到匹配后立即返回结果。
- 补数计算:对于当前元素
-
复杂度分析:时间复杂度:O(n),只需遍历数组一次。 空间复杂度:O(n),哈希表最多存储 n 个元素。
代码实现(Java版)🔥点击下载源码
class Solution {
public int[] twoSum(int[] nums, int target) {
// 创建哈希表:键为元素值,值为元素下标
HashMap<Integer, Integer> map = new HashMap<>(nums.length);
for (int i = 0; i < nums.length; i++) {
// 计算当前元素所需的补数
int complement = target - nums[i];
// 检查补数是否在哈希表中
if (map.containsKey(complement)) {
// 找到匹配:返回补数的下标和当前下标
return new int[]{map.get(complement), i};
}
// 将当前元素及其下标存入哈希表
map.put(nums[i], i);
}
// 题目保证有解,此句不会执行
return new int[0];
}
}
代码说明
-
初始化哈希表:
HashMap<Integer, Integer> map = new HashMap<>(nums.length)指定初始容量为数组长度,避免扩容开销。 -
遍历与补数计算:
- 遍历数组时,计算
complement = target - nums[i](当前元素所需的补数)。 - 若补数已存在于哈希表中(
map.containsKey(complement)),说明找到了两个数,返回它们的下标:补数的下标(map.get(complement))和当前下标i。
- 遍历数组时,计算
-
哈希表更新:
若未找到补数,将当前元素nums[i]及其下标i存入哈希表,供后续查询使用。 -
终止条件:
- 题目保证有唯一解,因此循环内必会返回结果。
- 循环外的
return new int[0]仅为语法需要,实际不会执行。
示例演示: 以 nums = [2, 7, 11, 15], target = 9 为例:
i=0:补数9-2=7不在哈希表 → 存入(2,0)。i=1:补数9-7=2在哈希表中 → 返回[0,1]。
提交详情(执行用时、内存消耗)


603

被折叠的 条评论
为什么被折叠?



