❓题目:
给定一个整数数组
nums
和一个目标值target
,判断是否存在两个数相加等于target
,返回布尔值。
例如:
int[] nums = {2, 7, 11, 15};
int target = 9;
// 返回 true,因为 2 + 7 = 9
🧠 解法一:暴力双循环
实现:
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return true;
}
}
}
return false;
⏰ 时间复杂度分析:
-
两层嵌套循环 → 每层最多 n 次
-
所以执行次数大约是
n * n = n²
-
时间复杂度:O(n²)
💾 空间复杂度分析:
-
没有使用任何额外的存储结构。
-
空间复杂度:O(1)
🧠 解法二:使用 HashSet 优化(空间换时间)
思路:
我们在遍历的同时,用一个 HashSet 存下已经看过的数字。
每看一个数 x
,判断 target - x
是否已经存在,如果存在,则找到了两个数。
实现:
Set<Integer> seen = new HashSet<>();
for (int num : nums) {
if (seen.contains(target - num)) {
return true;
}
seen.add(num);
}
return false;
⏰ 时间复杂度分析:
-
遍历一次数组 → n 次
-
HashSet 查找、插入都是 O(1) 平均复杂度
-
总时间复杂度:O(n)
💾 空间复杂度分析:
-
最坏情况下,要存下所有 n 个数字
-
使用了一个大小为 n 的 HashSet
-
空间复杂度:O(n)
📊 对比总结表格:
解法 | 时间复杂度 | 空间复杂度 | 思路 |
---|---|---|---|
暴力双循环 | O(n²) | O(1) | 穷举所有组合 |
HashSet优化 | O(n) | O(n) | 边查边存,空间换时间 |
📌 面试答题模板:
这道题我们可以先用暴力法解决,时间复杂度是 O(n²),空间是 O(1)。为了优化时间性能,我们可以用 HashSet 在一遍遍历中查找另一个数,时间复杂度降到 O(n),但需要 O(n) 的额外空间存储已遍历元素。这属于典型的空间换时间的优化策略。
🧠 延伸理解关键词:
-
空间换时间:用额外的内存(比如 HashMap、HashSet、数组缓存等)换取查找/计算效率。
-
时间换空间:少用空间(不建新结构),但可能导致重复运算、性能低。