【LeetCode 题解】两数之和(C++/Python 双解法):从语法到算法的全面解析

article/2025/7/14 15:46:02

【LeetCode题解】两数之和(C++/Python双解法):从语法到算法的全面解析

一、题目描述

题目链接:1. 两数之和
难度:简单
要求:给定一个整数数组 nums 和一个整数目标值 target,在数组中找出两个数,使其和为 target,并返回它们的下标。
限制:每个输入只对应唯一解,且不能重复使用同一个元素。

二、解法思路:哈希表(最优解)

2.1 核心思想

  • 暴力枚举:遍历每个元素,再嵌套遍历寻找补数(target - nums[i]),时间复杂度为 O(n²),效率低。
  • 哈希表优化:用哈希表(字典)存储元素及其下标,遍历数组时,对每个元素 nums[i],检查补数是否已在哈希表中:
    • 若存在,直接返回补数的下标和当前下标。
    • 若不存在,将当前元素和下标存入哈希表,供后续元素查找。
  • 时间复杂度:O(n),只需遍历数组一次。
  • 空间复杂度:O(n),哈希表存储最多 n 个元素。

2.2 哈希表原理图解

哈希表查找补数示意图

三、代码实现

3.1 Python 解法

常规版(适合LeetCode直接提交)
from typing import Listclass Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:d = {}  # 键:元素值,值:下标for i in range(len(nums)):complement = target - nums[i]if complement in d:return [d[complement], i]d[nums[i]] = ireturn []  # 题目保证有解,此句可省略
ACM版(适合本地ACM模式输入)
# 读取输入
import sysdef main():data = list(map(int, sys.stdin.read().split()))n = data[0]target = data[1]nums = data[2: 2+n]d = {}for i in range(n):complement = target - nums[i]if complement in d:print(d[complement], i)returnd[nums[i]] = iif __name__ == "__main__":main()

ACM输入说明

  • sys.stdin.read() 读取全部输入,适用于多行或连续输入场景。
  • 输入格式示例:4 9 2 7 11 15(依次为n, target, 数组元素)。

3.2 C++ 解法

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> numToIndex; // 哈希表:存储元素值到下标的映射for (int i = 0; i < nums.size(); i++) {int complement = target - nums[i];// 查找补数是否在哈希表中if (numToIndex.find(complement) != numToIndex.end()) {return {numToIndex[complement], i}; // C++11列表初始化}numToIndex[nums[i]] = i; // 存入当前元素和下标}return {}; // 题目保证有解,此句可省略}
};// 主函数(ACM输入模式)
int main() {int n, target;cin >> n >> target; // 读取n和targetvector<int> nums(n); // 创建长度为n的数组for (int i = 0; i < n; i++) {cin >> nums[i]; // 读取数组元素}Solution solution;vector<int> result = solution.twoSum(nums, target);cout << result[0] << " " << result[1] << endl; // 输出结果return 0;
}
// #include <xxx> 引入工具包 
#include <iostream>         // 输入输出 cin >> 输入  cout << 输出
#include <unordered_map>    // 哈希工具包, 快速查询字典
#include <vector>           // 动态工具包, 存储一组数组using namespace std;         // 简化代码, 标准库工具。后面用到工具时, 不用写std:: 前缀// 类和函数!
class Solution {             // class是模板, Solution是模板名字// 比如“汽车”是个模板, 里面包含"启动", "刹车"等功能
public:     //模板里面的功能默认是“私有的”, public 让后面的函数可以被外部调用!vector<int> twoSum(vector<int>& nums, int target) {/*  vector<int> twoSum(...) 表示twoSum这个函数的返回值是一组整数(动态数组) vector<int>twoSum 函数名称vector<int>& nums 是函数输入的一组整数(vector<int>)& 表示“引用”, 直接使用原始数据, 不复制一份int target 另一个输入参数  */unordered_map<int, int> numToIndex; // 创建一个哈希表 <数字, 下标>for (int i = 0; i < (int)nums.size(); i++) {// for (起点 ; )int complement = target - nums[i]; // 计算需要的补数 // numToIndex.find(complement) 是在哈希表中查找是否有“单词”(“键值对中的键”)等于complement// 如果find到complement:返回这个单词对应的条目// 如果没找到,返回一个特殊标记 告诉我们 字典中没有这个单词!// end()方法: 是一个虚拟位置,字典的最后一个条目的后面 就是空!// 所以 如果find(xx) == end()  就是没找到这个单词if (numToIndex.find(complement) != numToIndex.end()) {// 如果补数complement就在哈希表中,如果找到了 且不等于end()return { numToIndex[complement], i };}// 如果没找到,把当前数和下标放入哈希表numToIndex[nums[i]] = i;}return {};}
};// main()函数是程序的入口
int main(){int n, target;cin >> n >> target; // cin >> ... >> ... 输入vector<int> nums(n);for (int i = 0; i < n; i++) {cin >> nums[i]; // 读取n个整数存入数组}Solution solution; // 创建一个Solution类型的对象(类似造一辆车!名字叫做solution)vector<int> result = solution.twoSum(nums, target);cout << result[0] << " " << result[1] << endl;return 0;
}

四、C++语法关键点解析

4.1 分号 ; 的使用规则(超详细总结)

4.1.1 必须加分号的情况
场景示例代码说明
语句末尾int a = 10; cout << "a";每个完整语句结束后必须加分号
单行控制流语句if (a>0) cout << "正数";单行if/while语句末尾加分号
类成员声明class A { int x; void f(); };成员变量和函数声明后加分号
枚举/联合体定义enum Color {RED, GREEN};定义末尾必须加分号
4.1.2 绝对不加分号的情况
场景错误代码正确代码说明
函数体结束 }void f() { ... };void f() { ... }函数体大括号后不加分号
预处理指令#include <iostream>;#include <iostream>#include等指令后不加分号
类定义结束 }class A { ... }class A { ... };唯一例外:类定义后必须加分号
大括号代码块内部if (a) { cout << "a"; ; }if (a) { cout << "a"; }大括号内语句末尾加分号,括号后不加
4.1.3 易混淆场景对比
// 正确:类定义后加分号
class Solution { // 成员函数
}; // 错误:函数体后加分号
int main() { // 代码块
}; // ❌ 多余分号

4.2 哈希表关键操作:find vs end

unordered_map<int, int> numToIndex;
if (numToIndex.find(complement) != numToIndex.end()) {// 找到补数,返回下标
}
  • find(key):在哈希表中查找键 key,若存在返回对应迭代器,否则返回 end()
  • end():返回一个指向哈希表“虚拟末尾”的迭代器,用于判断查找是否失败。
  • 类比:相当于在字典中查找单词,找到返回单词位置,找不到返回“字典最后一页的下一页”(不存在)。

五、常见错误与解决方案

5.1 C++编译错误:unordered_map 未声明

  • 原因:未启用C++11标准,或头文件缺失。
  • 解决方案
    1. 添加 #include <unordered_map>
    2. 编译时加参数 -std=c++11
      g++ code.cpp -o output -std=c++11
      

5.2 类定义末尾缺少分号

class Solution { // 成员函数
} // ❌ 错误:缺少分号
  • 修正:在类定义结束的 } 后添加分号:
    class Solution { // 成员函数
    }; // ✅ 正确
    

5.3 Python ACM输入错误:下标越界

  • 原因:输入格式错误,如未正确解析n和数组长度。
  • 解决方案:确保输入数据长度正确,如 nums = data[2: 2+n] 需与n匹配。

六、总结

6.1 算法优化对比

方法时间复杂度空间复杂度适用场景
暴力枚举O(n²)O(1)n很小的情况
哈希表O(n)O(n)大规模数据

6.2 学习建议

  1. C++语法:重点掌握分号规则、命名空间、STL容器(如vectorunordered_map)。
  2. 算法思维:学会用哈希表优化查找问题,理解空间换时间的思想。
  3. 代码习惯
    • 编译C++时默认启用C++11(-std=c++11)。
    • 用IDE(如VS Code)实时检查语法错误。

示例输入输出

  • 输入:nums = [2,7,11,15], target = 9
  • 输出:[0, 1]
  • 解释:2 + 7 = 9,下标分别为0和1。

作者:CodeIsLife
博客链接:https://blog.csdn.net/CodeIsLife
转载请注明出处
欢迎在评论区交流疑问,觉得有帮助可以点赞收藏~ 😊


http://www.hkcw.cn/article/jTVXLlTPUG.shtml

相关文章

《AI Agent项目开发实战》DeepSeek R1模型蒸馏入门实战

一、模型蒸馏环境部署 注&#xff1a;本次实验仍然采用Ubuntu操作系统&#xff0c;基本配置如下&#xff1a; 需要注意的是&#xff0c;本次公开课以Qwen 1.5-instruct模型为例进行蒸馏&#xff0c;从而能省略冷启动SFT过程&#xff0c;并且 由于Qwen系列模型本身性能较强&…

17.进程间通信(三)

一、System V 消息队列基本结构与理解 消息队列是全双工通信&#xff0c;可以同时收发消息。 结论1&#xff1a;消息队列提供了一种&#xff0c;一个进程给另一个进程发送有类型数据块的方式&#xff01; 结论2&#xff1a;OS中消息队列可能有多个&#xff0c;要对消息队列进行…

【汽车电子入门】一文了解LIN总线

前言&#xff1a;LIN&#xff08;Local Interconnect Network&#xff09;总线&#xff0c;也就是局域互联网的意思&#xff0c;它的出现晚于CAN总线&#xff0c;于20世纪90年代末被摩托罗拉、宝马、奥迪、戴姆勒、大众以及沃尔沃等多家公司联合开发&#xff0c;其目的是提供一…

BayesFlow:基于神经网络的摊销贝叶斯推断框架

贝叶斯推断为不确定性条件下的推理、复杂系统建模以及基于观测数据的预测提供了严谨且功能强大的理论框架。尽管贝叶斯建模在理论上具有优雅性&#xff0c;但在实际应用中经常面临显著的计算挑战&#xff1a;后验分布通常缺乏解析解&#xff0c;模型验证和比较需要进行重复的推…

高压电绝缘子破损目标检测数据集简介与应用

在电力系统中&#xff0c;高压电绝缘子起着关键的绝缘与机械支撑作用。一旦发生破损&#xff0c;不仅影响输电线路的安全运行&#xff0c;还可能引发电力事故。因此&#xff0c;利用目标检测技术对高压绝缘子的破损情况进行智能识别&#xff0c;已成为当前电力巡检中的重要研究…

深度学习与神经网络 前馈神经网络

1.神经网络特征 无需人去告知神经网络具体的特征是什么&#xff0c;神经网络可以自主学习 2.激活函数性质 &#xff08;1&#xff09;连续并可导&#xff08;允许少数点不可导&#xff09;的非线性函数 &#xff08;2&#xff09;单调递增 &#xff08;3&#xff09;函数本…

paoxiaomo的XCPC算法竞赛训练经验

楼主作为一个普通二本的ICPC选手&#xff0c;在0基础的情况下凭借自学&#xff0c;获得过南昌邀请赛金牌&#xff0c;杭州区域赛银牌&#xff0c;一路上经历过不少的跌宕起伏&#xff0c;如今将曾经摸索出来的学习路线分享给大家 一&#xff0c;语言基础 学习C语言基础语法&a…

电力系统时间同步系统

电力系统中&#xff0c;电压、电流、功率变化等特征量测量都是时间相关函数[1]&#xff0c;统一精准的时间源对于电网安全稳定运行至关重要&#xff0c;因此&#xff0c;电力系统运行规程[2]中明确要求继电保护装置、自动化装置、安全稳定控制系统、能量管理系统和生产信息管理…

Codeforces Round 1028 (Div. 2)(A-D)

题面链接&#xff1a;Dashboard - Codeforces Round 1028 (Div. 2) - Codeforces A. Gellyfish and Tricolor Pansy 思路 要知道骑士如果没了那么这个人就失去了攻击手段&#xff0c;贪心的来说我们只需要攻击血量少的即可&#xff0c;那么取min比较一下即可 代码 void so…

金属材料资料

一、金属材料 1. 黑色金属材料&#xff08;钢铁材料&#xff09; 铸铁&#xff08;含碳量&#xff1e;2.11%&#xff09; 分类&#xff1a; 按碳存在形式&#xff1a;白口铸铁&#xff08;硬脆&#xff0c;炼钢原料&#xff09;、灰口铸铁&#xff08;应用最广&#xff09;、…

mysql专题上

连接服务器 mysql -h 127.0.0.1 -P 3306 -u root -p -h后接的是要连接的部署了mysql的主机&#xff0c;127.0.0.1指的是单机访问&#xff0c;如果没有指令则直接连接本地 -P后接的是端口号 一般是3306 -u后接的是要登入的用户 -p指要登陆密码 如果要退出可以直接quit mysql…

DAY43打卡

浙大疏锦行 kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 fruit_cnn_project/ ├─ data/ # 存放数据集&#xff08;需手动创建&#xff0c;后续放入图片&#xff09; │ ├─ train/ …

蓝天影院订票网站的设计V3

1 绪 论 1.1 本课题研究背景 20世纪90年代中期以来&#xff0c;随着以Internet为代表的计算机技术&#xff0c;网络技术和信息技术的迅速发展&#xff0c;影院订票也逐渐转移到网络上[1][2]。伴随着我国计算机信息产业的飞速进步&#xff0c;计算机的开发应用已经遍布生活…

Python----目标检测(《YOLO9000: Better, Faster, Stronger》和YOLO-V2的原理与网络结构)

一、YOLO9000: Better, Faster, Stronger 1.1、基本信息 标题: YOLO9000: Better, Faster, Stronger 作者: Joseph Redmon, Ali Farhadi 机构: 华盛顿大学1, 艾伦人工智能研究所2 发布时间: 2016年&#xff08;根据arXiv编号1612.08242推断&#xff09; 论文链接: [1612.0…

力扣HOT100之动态规划:32. 最长有效括号

这道题放在动态规划里属实是有点难为人了&#xff0c;感觉用动态规划来做反而更难理解了&#xff0c;这道题用索引栈来做相当好理解&#xff0c;这里先讲下索引栈的思路。 索引栈做法 我们定义一个存放整数的栈&#xff0c;定义一个全局变量result来记录最长有效子串的长度&a…

操作系统:文件系统笔记

文件系统 参考资料&#xff1a; 12.10 虚拟文件系统_哔哩哔哩_bilibili7.1 文件系统全家桶 | 小林coding 基本组成 文件系统是操作系统中负责管理持久数据的子系统&#xff0c;说简单点&#xff0c;就是负责把用户的文件存到磁盘硬件中&#xff0c;因为即使计算机断电了&#…

Docker 安装 Redis 容器

系列文章目录 文章目录 系列文章目录前言1 获取redis镜像2 创建和部署redis容器3 查看redis是否启动成功4 使用Redis客户端验证连接总结 前言 搭建环境&#xff1a; ubuntu22.04.05 docker redis: 7.0.10 测试环境&#xff1a; windows: win11 Redis测试客户端&#xff1a;Ti…

Spring Boot 3.X 下Redis缓存的尝试(二):自动注解实现自动化缓存操作

前言 上文我们做了在Spring Boot下对Redis的基本操作&#xff0c;如果频繁对Redis进行操作而写对应的方法显示使用注释更会更高效&#xff1b; 比如&#xff1a; 依之前操作对一个业务进行定入缓存需要把数据拉取到后再定入&#xff1b; 而今天我们可以通过注释的方式不需要额外…

【Linux】Ubuntu 20.04 英文系统显示中文字体异常

英文系统显示中文字体异常 新安装的 Ubuntu 20.04 英文系统&#xff0c;显示中文字体有些奇怪&#xff0c;比如在谷歌浏览器中中文字体显示效果如下 参考 英文版ubuntu默认中文显示很奇怪 解决方案 - dbxxx - 博客园 编辑文件 sudo gedit /etc/fonts/conf.avail/64-languag…