【题解】Leetcode #1. 两数之和
题意简述
给定整数数组nums
(以下简写为\(a\))和目标值target
(以下简写为\(t\)),求一组\((i,j)\),其中\(0\leq i,j<n\),使得\(a_i+a_j=t\)。
思路
我们来考虑暴力枚举。根据题意明显可以两层循环分别枚举\(i\)和\(j\),当找到符合题意的一组\((i,j)\)时,直接输出。时间复杂度\(O(n^2)\),用leetcode
水爆了的数据显然能过。
【代码】
class Solution
{
public:
#define n nums.size()
vector<int> twoSum(vector<int>& nums, int target)
{
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 {};
}
};
运行数据:71ms/12.67MB
如何考虑更优的时间复杂度?我们注意到如果我们能够用\(O(1)\)的时间来处理和查询在先前的遍历中找到的数据信息反向映射,这样可以将时间复杂度优化到\(O(n)\),但是额外代价就是消耗了复杂度为\(O(n)\)的空间。我们的正向映射是题目中已经给出的,反向映射就不得不提到我们今天算法的主角:哈希表。
这样我们创建一个哈希表,对于每一个\(x\),我们首先查询哈希表中是否存在\(t - x\),然后将\(x\)插入到哈希表中,即可保证不会让\(x\)和自己匹配。
【代码】
class Solution
{
public:
#define n nums.size()
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int, int> mp;
for (int i = 0; i < n; i++)
{
if (mp.find(target - nums[i]) != mp.end())
return {mp[target - nums[i]], i};
mp[nums[i]] = i;
}
return {};
}
};
运行数据:14ms/14.04MB
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验