1. 两数之和题解
题目描述
[!NOTE]
总结:找出整数数组中两数之后等于目标值的两个数,然后返回其下标
给定一个整数数组 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
- 只会存在一个有效答案
题解
暴力法
通过两个循环,遍历所有可能结果。时间复杂度为\(O(n^2)\)。
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
int i, j;
bool flag = false;
for (i = 0; (i < nums.size() - 1) && !flag; i++)
{
for (j = i + 1; j < nums.size() && !flag; j++)
{
if (nums[i] + nums[j] == target)
flag = true;
}
}
return vector<int>{i - 1, j - 1};
}
};
[!NOTE]
for(initialization; condition; increment)
循环执行顺序。
- 初始化。只在第一次循环中执行。
- 条件判断。符合条件才能执行循环体。
- 自增。执行完循环体后,就自增,再去进行条件判断。而不是先进行条件判断,再自增。
- 条件判断。
- 自增
- …
哈希表
遍历数组,以<target - num[i], i>
的方式存储哈希值(前者为哈希表的值,后者为索引下标)。整体只需要一次遍历,时间复杂度为\(O(n)\)。无序哈希表的查找复杂度为\(O(1)\),而有序哈希表的查找复杂度为\(O(lg(n)\) 。没有需求的话,一般都用无序哈希表。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> uMap;
unordered_map<int, int>::iterator iter;
int i;
for (i = 0; i < nums.size(); i++) {
iter = uMap.find(target - nums[i]); // 可以直接auto iter
if (iter != uMap.end()) {
break;
}
uMap.insert({i, nums[i]});
}
return {iter->first, i}; // iter->first 是键还是值,取决于insert插入的方式
}
};
常用API介绍
引入库,#include<unordered_map>
-
insert()
:插入键值对,如果已经存在,则插入失败。-
insert({index, value})
-
insert(pair(index,value))
-
-
获取键值对
-
iter->first
-
iter->second
-
map[index]
:只获取值
-
-
find()
:查找哈希表中是否存在这个键。如果存在,则返回指向该键值对的迭代器;如果不存在,返回end()
迭代器。-
auto iter = umap.find(2); // 或者 unordered_map <int,int>::iterator iter = umap.find(2); if(iter != umap.end()) cout << "查找成功" << endl;
-
-
erase()
:删除指定键及其对应的键值对umap.erase(index)
-
empty()
:判断是否为空,返回布尔值。 -
clear()
:清空哈希表。