🏠关于专栏:专栏用于记录LeetCode中Hot100专题的所有题目
🎯每日努力一点点,技术变化看得见
题目转载
题目描述
🔒link->题目跳转链接
给定一个整数数组 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
2
2 <= nums.length <=
1
0
4
10^4
104
●
−
1
0
9
-10^9
−109 <= nums[i] <=
1
0
9
10^9
109
●
−
1
0
9
-10^9
−109 <= target <=
1
0
9
10^9
109
● 只会存在一个有效答案
🔍进阶: 你可以想出一个时间复杂度小于 O ( n 2 ) O(n^2) O(n2) 的算法吗?
解题思路及代码
[1]暴力枚举
一眼可以想到的就是让所有数字两两匹配,则我们可以使用两层for循环。但题目要求不能使用同一个元素,下方代码中如果内外层循环下标相等时,即表示同一个元素,需要跳过。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for(int i = 0; i < nums.size(); ++i)
{
for(int j = 0; j < nums.size(); ++j)
{
if(i == j) continue; //表示同一个元素,跳过
if(nums[i] + nums[j] == target) return {i, j};
}
}
return {};
}
};
对于两两匹配的算法来说,可以做出如下优化。上述实现代码中,当外循环为1时,它与2组合过了;但当外循环为2是,它又与1组合了1次,这出现了重复组合的情况,降低了效率。下图左侧还给出了其他重复比较的地方(2和1、3和1、3和2均出现了重复比较)。可将其优化为右侧方式,避免重复比较,提高效率。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for(int i = 0; i < nums.size(); ++i)
{
// 不再与小于i的元素组合
for(int j = i + 1; j < nums.size(); ++j)
{
if(nums[i] + nums[j] == target) return {i, j};
}
}
return {};
}
};
[2]哈希表
上述代码的效率是
O
(
N
2
)
O(N^2)
O(N2)的,效率比较低。我们可以借助于哈希表将时间效率提高为
O
(
1
)
O(1)
O(1)。逻辑思路为:构建一个哈希表,其存储的元素为一个键值对,first域为具体的数值,second域为数值在nums数组的下标;当遍历到第index元素elem时,就在哈希表中查找target-elem,如果存在则返回target-elem的second域和index即可,若不存在则将当前元素的值和下标保存到哈希表中。逻辑思路图如下图所示。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
for(int i = 0; i < nums.size(); ++i)
{
auto des = m.find(target - nums[i]);
if(des != m.end())
{
return {des->second, i};
}
else
{
m[nums[i]] = i;
}
}
return {};
}
};
刷题使我快乐😭
文章如有错误,请私信或在下方留言😀