[LeetCode] 1. 两数之和
1. 问题描述
给定一个整数数组 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 <= 104109 <= nums[i] <= 109109 <= target <= 109- 只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
2. 实现思路
2.1 自己的思路
~~(唔,所以一定要写出来啊喂)~
选两个数出来判断,最简单的暴力枚举,时间复杂度O(n2)
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 {0, 0};
}
};
2026年8月8日 14:31
啊看到去年刚接触算法题的时候,感觉过去了好久,也学了很多东西
本来一开始想用HashSet的,但发现不太好确定差的数组下标,就改用dict了
思路是遍历数组时,同时在dict里找差是否已经存在,如果存在说明就出结果了
/*
* @lc app=leetcode.cn id=1 lang=csharp
*
* [1] 两数之和
*/
// @lc code=start
public class Solution
{
public int[] TwoSum(int[] nums, int target)
{
var h = new Dictionary<int, int>();
for (int i = 0; i < nums.Length; i++)
{
if (!h.Keys.Contains(target - nums[i]))
h[nums[i]] = i;
else
return [i, h[target - nums[i]]];
}
return [];
}
}
// @lc code=end
2.2 题解思路
先看随想录的解法
1. 两数之和|哈希表 Map 解法|O(n)时间复杂度|数组查找算法核心技巧
- 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
- set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。
思路和我的解法差不多诶


C++:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
std::unordered_map <int,int> map;
for(int i = 0; i < nums.size(); i++) {
// 遍历当前元素,并在map中寻找是否有匹配的key
auto iter = map.find(target - nums[i]);
if(iter != map.end()) {
return {iter->second, i};
}
// 如果没找到匹配对,就把访问过的元素和下标加入到map中
map.insert(pair<int, int>(nums[i], i));
}
return {};
}
};
逆向思维,遍历过程中用内置的find方法查找是否存在target-nums[i]即可
- 时间复杂度: O(n)
- 空间复杂度: O(n)
C#:
public class Solution {
public int[] TwoSum(int[] nums, int target) {
Dictionary<int ,int> dic= new Dictionary<int,int>();
for(int i=0;i<nums.Length;i++){
int imp= target-nums[i];
if(dic.ContainsKey(imp)&&dic[imp]!=i){
return new int[]{i, dic[imp]};
}
if(!dic.ContainsKey(nums[i])){
dic.Add(nums[i],i);
}
}
return new int[]{0, 0};
}
}
3. 补充知识と杂谈,总结
- unordered_map(生成自ChatGPT)
unordered_map 是 C++ 标准库中的一种容器,它是基于哈希表实现的,用于存储键值对(key-value pairs)。与 map 不同,unordered_map 的元素不按照键的顺序排序,而是通过哈希值来实现快速的查找、插入和删除操作。
主要特点:
- 无序存储:
unordered_map中的元素不保证按照键的顺序排列。它们是根据哈希函数计算得到的位置存储的。 - 平均时间复杂度:在理想情况下,查找、插入和删除的时间复杂度是常数时间 O(1),但如果哈希冲突很严重,复杂度可能会退化为 O(n)。
- 键唯一:每个键只能出现一次。如果插入一个已经存在的键,原有的键值对会被更新。
典型用法:
#include <iostream>
#include <unordered_map>
int main() {
// 创建一个 unordered_map,键是 int 类型,值是 string 类型
std::unordered_map<int, std::string> umap;
// 插入元素
umap[1] = "One";
umap[2] = "Two";
umap[3] = "Three";
// 查找元素
if (umap.find(2) != umap.end()) {
std::cout << "Found key 2 with value: " << umap[2] << std::endl;
}
// 遍历元素
for (const auto& pair : umap) {
std::cout << pair.first << " -> " << pair.second << std::endl;
}
return 0;
}
常见操作:
- 插入元素:
umap[key] = value;或umap.insert({key, value}); - 查找元素:
umap.find(key)返回一个迭代器指向该元素,若找不到返回umap.end()。 - 删除元素:
umap.erase(key); - 访问元素:
umap[key]可以直接访问或修改对应键的值。
注意事项:
- 使用
unordered_map时需要指定一个合适的哈希函数,特别是对于自定义类型的键,如果没有提供哈希函数,编译器会尝试默认的哈希。 unordered_map的元素顺序不固定,每次打印可能会看到不同的顺序。
一些重点自查list
- 为什么想到用哈希表?
- 哈希表为什么用map/dict?
- 本题map用来存什么的?
- key和value的含义?
如果有补充/纠正,欢迎在评论区留言(≧▽≦)/

浙公网安备 33010602011771号