给定一个整数数组 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 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- 只会存在一个有效答案
1. 暴力解法,代码如下:
#include<iostream>
#include<vector>
using namespace std;
class Solution{
public:
//核心代码(题目答案)
vector<int> twosum(vector<int>& nums, int target)
{
int flag = 0;
vector<int>answer;//答案数组,即两个符合条件的元素下标组合
for(unsigned int i = 0; i < nums.size(); i++)
{
if(flag == 1) break;//提前退出循环的条件
for(unsigned int j = i + 1; j < nums.size(); j++)
{
if(nums[i] + nums[j] == target)
{
flag = 1;
answer.push_back(i);
answer.push_back(j);//将两个元素的下标压入容器内
break;
}
}
}
return answer;
}
};
//自验代码
int main()
{
vector<int> question;
int n, t, p; //t为中间变量,代表每一个输入的元素值
cin >> n >> p; //n为数组长度,p为目标值
for(int l = 0; l < n; l++)
{
cin >> t;
question.push_back(t);//初始化目标数组
}
Solution s;
question = s.twosum(question, p);
for(unsigned int q = 0; q < question.size(); q++)
{
cout << question[q];
if(q == question.size() - 1) cout << endl;
else cout << ",";
}
cout << "this is a test for complination!" << endl;
return 0;
}
/*作者:CaiCode
链接:https://leetcode.cn/problems/two-sum/solutions/2374442/bian-yi-ge-zi-ji-ce-shi-de-bao-li-mei-ju-uzsk/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/
暴力遍历的算法,通过两次遍历数组的方式,找到符合求和为目标值的两个元素对应的下标,将其压入容器内,只有唯一的答案,故找到之后即可退出循环并打印,也可以先打印后直接return。
2. 利用哈希表查找和搜索的思想,代码如下:
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
class Solution{
public:
//核心代码(题目答案)
vector<int> twosum(vector<int>& nums, int target)
{
unordered_map<int, int> hashtable;//创建哈希表,键值对均为整型
for(int i = 0; i < nums.size(); i++)//遍历给定的数组
{
auto it = hashtable.find(target - nums[i]);//在哈希表内查找是否有与当前数组元素配对的值,设置一个变量存储其下标
//判断该下标(迭代器)是否是哈希表中最后一个元素的下一个迭代器,即看是否查找了整个哈希表但仍然未找到与其对应的值。
if(it != hashtable.end())
{
return {it->second, i};//如果不是则说明哈希表中有对应的值,直接返回由该迭代器对应的值以及当前数组元素的下标构成的组合。
}
hashtable[nums[i]] = i;//如果是则说明在哈希表中未找到对应的值,将该元素值以及对应的下标添加到哈希表中以供后面的元素匹配。
}
return {};//应对函数返回值空问题
}
};
//自验代码
int main()
{
vector<int> question;
int n, t, p;
cin >> n >> p;
for(int l = 0; l < n; l++)
{
cin >> t;
question.push_back(t);
}
Solution s;
question = s.twosum(question, p);
for(unsigned int q = 0; q < question.size(); q++)
{
cout << question[q];
if(q == question.size() - 1) cout << endl;
else cout << ",";
}
cout << "this is a test for complination!" << endl;
return 0;
}
/*作者:CaiCode
链接:https://leetcode.cn/problems/two-sum/solutions/2378674/bian-xie-yi-ge-ke-zhi-xing-de-ha-xi-biao-vx7d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/
- 哈希表的键值对{key, value}中的key在本题中对应的是数组元素值,value对应的是数组元素的下标。可以用find函数或者count函数查找是否有对应元素的存在。find函数会返回一个迭代器,等于end则说明没有,否则就有;而count函数则会返回一个整数代表该key值对应的元素个数,unordered_map不允许重复元素则返回0或1,0代表没有,1代表有。
用哈希表查找采用了拿空间换时间的思想,时间复杂度大大降低,空间复杂度有所提高。因为最多只要遍历一次数组O(n),而暴力枚举需要最多遍历两次数组O(n^2);创建了一个供查找的哈希表,空间复杂度即为哈希表的长度O(n),暴力枚举只用了几个循环变量O(1)。