两数之和
# 📃 题目描述
题目链接:1. 两数之和 - 力扣(LeetCode) (leetcode-cn.com) (opens new window)
给定一个整数数组 nums 和一个整数目标值 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]
# 🔔 解题思路
最简单的思路就是穷举,嵌套遍历,不过显然时间复杂度太高:
class Solution {
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[0];
}
}
可以通过一个哈希表减少时间复杂度:哈希表的 key 对应元素的值,哈希表的 value 对应元素的下标(因为题目需要返回的就是下标),比如某个元素值为 2,就将这个元素的下标存放在哈希表的 key = 2 的 value 上。这样,我们只需要遍历一遍数组,查看 map 中 target - nums[i] 对应的键值对是否存在(并且还要注意这个数不能是 nums[i] 本身),就能知道有没有元素能和 2 组成 target 了。
class Solution {
public int[] twoSum(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return new int[0];
}
// key: 元素值, value: 元素下标
Map<Integer, Integer> map = new HashMap<>();
// 处理数组存入 map
for (int i = 0; i < nums.length; i ++) {
map.put(nums[i], i);
}
// 遍历数组
for (int i = 0; i < nums.length; i ++) {
// 当前元素 nums[i] + j = target
int j = target - nums[i];
// 在 map 中查找下 j 对应的键值对是否存在, 并且还要注意这个数不能是 nums[i] 本身
if (map.containsKey(j) && map.get(j) != i) {
return new int[]{i, map.get(j)};
}
}
return new int[0];
}
}
# 💥 复杂度分析
穷举法:
- 空间复杂度:O(1)
- 时间复杂度: O(N^2)
哈希表:
- 空间复杂度:需要 O(N) 的空间复杂度来存储哈希表
- 时间复杂度:算法的时间复杂度降低到 O(N)
综合来看,哈希表是要比暴力循环解法高效的
🎁 公众号

各位小伙伴大家好呀,叫我小牛肉就行,目前在读东南大学硕士,上方扫码关注公众号「飞天小牛肉」,与你分享我的成长历程与技术感悟~
帮助小牛肉改善此页面 (opens new window)
Last Updated: 2023/02/16, 11:27:10