仅做记录,并非最优解,仅供参考
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
【题目】给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
【说明】你可以假设每种输入只会对应一个答案,只会存在一个有效答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- 示例 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]
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
暴力解法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
for (int i = 0; i < n; i++){
for (int j = i+1; j < n; j++){
if (nums[i] + nums[j] == target){
return {i, j};
}
}
}
return {};
}
};
借助哈希表
C++中,哈希表是通过STL的std::unordered_map
来表示的(用法见文章末尾)。它是一个关联容器,存储了键-值对,并通过哈希函数对键进行散列来实现快速的增删改查。由于哈希函数的使用,这种数据结构在平均情况下具有常数时间复杂度
O
(
1
)
O(1)
O(1)。但还是复杂度比数组随机访问要高得多。
如果只存键,不存值,应选用std::unordered_set
,但对这道题而言,先把数组的所有元素复制到map中,其中map的键存放的是数组的每个元素值,而值则是每个元素对应的下标,因此用unordered_map
。遍历数组,计算目标值target与当前数组元素的差值,在map中寻找与这个差值相等的键,找到则返回,没找到则换下一个数组元素继续上面步骤。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
// 哈希表,额外空间O(N) 查找速度O(1)
std::unordered_map<int, int> map;
int i = 0;
for (; i <nums.size(); i++){ // O(N)
map.insert(std::make_pair(nums[i], i));
}
for (i = 0; i < nums.size(); i++){ // O(N)
int t = target - nums[i];
if (map.find(t) != map.end()){
if (i != map[t]) // 返回值不能是同一个下标
return {i, map[t]};
else
continue;
}
}
return {};
}
};
-
键-值对,用
std::unordered_map
- 增:
insert()
删:erase(),clear()
改:没有改操作
查:find(), count()
#include <unordered_map> #include <string> #include <iostream> int main(){ std::unordered_map<std::string, int> hashMap; // 增 hashMap["apple"] = 5; hashMap.insert(std::make_pair("banana", 3)); // 删 hashMap.erase("banana"); // hashMap.clear()清空 // 改 hashMap["apple"] = 4 // 改 // 查 if (hashMap.find("apple") != hashMap.end()) std::cout << "键apple存在" << std::endl; if (hashMap.count("apple") > 0) // 1则有,0则无 std::cout << "键apple存在" << std::endl; return 0; }
- 增:
-
只有键,没有值,用
std::unordered_set
- 增:
[ ], insert(make_pair())
删:erase(),clear()
改:[ ]
查:find(), count()
#include <unordered_set> #include <string> int main(){ std::unordered_set<string> hashSet; hashSet.insert("apple"); hashSet.insert("banana"); hashSet.erease("banana"); if (hashSet.find("apple") != hasSet.end()) std::cout << "有apple" << std::endl; if (hashSet.count("apple") > 0) std::cout << "有apple" << std::endl; return 0; }
- 增:
-
放入哈希表的东西,如果是基础类型,内部按值传递,内存占用为这个值所需空间大小
-
放入哈希表的东西,如果是自定义类型,内部按引用传递,内存占用为指针所需大小