LeetCode 2 - 两数相加

LeetCode 2 - 两数相加 是一道经典链表操作问题,经常作为面试中基础题的变体被考察。掌握多种解法及其变体,并熟悉其核心思路和模板代码,可以快速备战相关链表或大数计算问题。


题目描述

给定两个非空链表,它们代表两个非负整数,每个节点保存一个数字,数字按 逆序存储(个位在链表头部),求两个数的和并返回一个新的链表,表示其逆序和。

  • 输入:两个链表,l1 表示整数 a,l2 表示整数 b。
  • 输出:表示结果 a + b 的链表。

示例:

输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [7,0,8]
解释: 342 + 465 = 807

解法及其分析

解法 1:模拟加法(逐位相加)

思路
  • 链表表示逆序存储的数字,相当于按从低位到高位逐位对齐相加,因此直接模拟两数加法过程:
    1. 遍历两个链表,从头到尾逐位相加,考虑进位。
    2. carry 表示当前进位值(初始为 0)。
    3. 若链表长度不相等,可补 0,即看成空位处理。
    4. 将每次相加后的结果(sum % 10)保存到新链表中。
  • 完成遍历后,如果 carry 不为 0,则需要在结果链表末尾补 1。
模板代码
class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode dummyHead = new ListNode(0); // 哑节点ListNode p1 = l1, p2 = l2, current = dummyHead;int carry = 0;// 遍历两个链表while (p1 != null || p2 != null) {int x = (p1 != null) ? p1.val : 0; // 当节点为空时看作 0int y = (p2 != null) ? p2.val : 0;int sum = x + y + carry; // 当前位和carry = sum / 10;       // 计算进位current.next = new ListNode(sum % 10); // 新节点保存当前位值current = current.next;// 前进指针if (p1 != null) p1 = p1.next;if (p2 != null) p2 = p2.next;}// 如果最后进位不为 0,添加额外节点if (carry > 0) {current.next = new ListNode(carry);}return dummyHead.next; // 返回去掉哑节点后的结果链表}
}
复杂度分析
  • 时间复杂度: O(max(m, n)),其中 mn 是两个链表的长度,需遍历长链表的每个节点。
  • 空间复杂度: O(1),除了结果链表外,没有使用额外空间。

解法 2:递归解法

思路
  • 使用递归模拟逐位相加的过程:
    • 每次处理一对链表节点,计算当前位的和以及进位。
    • 递归调用处理剩余链表部分,进位值通过函数参数传递。
  • 递归本质就是逆序链表的“从尾到头”的回溯计算。
模板代码
class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {return helper(l1, l2, 0);}private ListNode helper(ListNode l1, ListNode l2, int carry) {if (l1 == null && l2 == null && carry == 0) {return null; // 递归结束条件}int sum = carry;if (l1 != null) sum += l1.val;if (l2 != null) sum += l2.val;ListNode node = new ListNode(sum % 10); // 保存当前位node.next = helper((l1 != null) ? l1.next : null, (l2 != null) ? l2.next : null, sum / 10 // 进位传递到下一层递归);return node;}
}
复杂度分析
  • 时间复杂度: O(max(m, n)),需要递归处理每一位。
  • 空间复杂度: O(max(m, n)),递归调用栈的深度最大为链表长度。

解法 3:反转链表法(适用于顺序存储时)

核心问题

如果链表存储的是整数的正常顺序(高位在前),如何求两数和?

思路
  1. 若链表采用正序存储,则需要先将链表反转(采用常用 反转链表模板)。
  2. 使用解法 1 的逐位相加方法,计算链表和。
  3. 最后将结果链表反转,恢复顺序。
模板代码
class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {l1 = reverseList(l1);l2 = reverseList(l2);ListNode result = addTwoNumbersReversed(l1, l2);return reverseList(result);}// 反转链表private ListNode reverseList(ListNode head) {ListNode prev = null;while (head != null) {ListNode next = head.next;head.next = prev;prev = head;head = next;}return prev;}// 借助解法1,计算反转链表的和private ListNode addTwoNumbersReversed(ListNode l1, ListNode l2) {ListNode dummyHead = new ListNode(0);ListNode current = dummyHead;int carry = 0;while (l1 != null || l2 != null || carry != 0) {int x = (l1 != null) ? l1.val : 0;int y = (l2 != null) ? l2.val : 0;int sum = x + y + carry;current.next = new ListNode(sum % 10);carry = sum / 10;current = current.next;if (l1 != null) l1 = l1.next;if (l2 != null) l2 = l2.next;}return dummyHead.next;}
}
复杂度分析
  • 时间复杂度: O(m + n),反转链表和加法操作总共需要线性时间。
  • 空间复杂度: O(1),原地操作链表。

变体问题

1. 链表与整数数组转换
  • 将链表转换为整数数组,再处理运算,最后将结果转换回链表。
  • 对于大整数字符串输入,也可以使用类似思路。
2. 两个数字是否相等
  • 判断两个链表存储的整数是否相等。
3. 合并 k 个链表的和
  • 扩展为 k 个链表相加,这可以使用优先队列或逐链表合并。
4. 大数相加(整数以字符串形式存储)
  • 给定两个数字以字符串形式存储,模拟大数加法逻辑。
  • 和这道题的链表加法思路非常类似。
5. 减法模拟
  • 如果要求两个链表表示的数相减,稍作修改:
    • 按位模拟减法。
    • 借位处理时,考虑前一位减 1。

快速 AC 总结

  1. 熟记关键模块
    • 使用链表构造哑节点(dummyHead)。
    • 逐位相加时的循环结构与边界条件。
    • 进位处理逻辑(如 carry)。
  2. 应对变体问题
    • 若逆序时直接逐位相加,正序时先反转链表。
    • 若输入为整数数组或大数字符串,则手动模拟链表结构。
  3. 调试基础功能(链表遍历、构建和反转)
    • 熟悉链表的单步操作和空链表边界处理,无论变体或难度增加都可以高效应对。

通过练习核心模板和理解变体模式,可以轻松解决这类链表和数字计算相关的题目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/27097.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【漫话机器学习系列】112.逻辑回归(Logistic Regression)

逻辑回归(Logistic Regression)详解 1. 逻辑回归简介 逻辑回归(Logistic Regression)是一种广泛用于二分类任务的统计和机器学习方法,尽管它的名字中带有“回归”,但它实际上是一种分类算法。 在逻辑回归…

大模型function calling:让AI函数调用更智能、更高效

大模型function calling:让AI函数调用更智能、更高效 随着大语言模型(LLM)的快速发展,其在实际应用中的能力越来越受到关注。Function Calling 是一种新兴的技术,允许大模型与外部工具或API进行交互,从而扩…

通过 PromptTemplate 生成干净的 SQL 查询语句并执行SQL查询语句

问题描述 在使用 LangChain 和 Llama 模型生成 SQL 查询时,遇到了 sqlite3.OperationalError 错误。错误信息如下: OperationalError: (sqlite3.OperationalError) near "sql SELECT Name FROM MediaType LIMIT 5; ": syntax error [SQL: …

计算机毕业设计SpringBoot+Vue.js企业资产管理系统(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

从零开始:H20服务器上DeepSeek R1 671B大模型部署与压力测试全攻略

前言 最近,我有幸在工作中接触到了DeepSeek R1 671B模型,这是目前中文开源领域参数量最大的高质量模型之一。DeepSeek团队在2024年推出的这款模型,以其惊人的6710亿参数量和出色的推理性能,引起了业界广泛关注。 作为一名AI基础…

Qt 文件操作+多线程+网络

文章目录 1. 文件操作1.1 API1.2 例子1,简单记事本1.3 例子2,输出文件的属性 2. Qt 多线程2.1 常用API2.2 例子1,自定义定时器 3. 线程安全3.1 互斥锁3.2 条件变量 4. 网络编程4.1 UDP Socket4.2 UDP Server4.3 UDP Client4.4 TCP Socket4.5 …

计算机毕业设计SpringBoot+Vue.js公司日常考勤系统(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

基于单片机的智能宿舍管理系统(论文+源码)

2.1总体方案设计 本课题为智能宿舍的设计,整个系统架构如图2.1所示,整个系统在器件上包括了主控制器STM32单片机,LD3320语音识别模块,按键模块,串口通信模块,照明模块,窗帘控制模块家电控制模块…

弱监督语义分割学习计划(2)-使用CoT进行Open Vocabulary Label简单实现类激活图

零: 项目说明 是这样的一个事情,经过与deepseek的一番讨论和交流,DeepSeek为我设计了一个30天高强度学习计划,重点聚焦弱监督/无监督语义分割在野外场景的应用,结合理论与实践,并最终导向可落地的开源项目。目前开始了…

RabbitMQ操作实战

1.RabbitMQ安装 RabbitMQ Windows 安装、配置、使用 - 小白教程-腾讯云开发者社区-腾讯云下载erlang:http://www.erlang.org/downloads/https://cloud.tencent.com/developer/article/2192340 Windows 10安装RabbitMQ及延时消息插件rabbitmq_delayed_message_exch…

力扣27.移除元素(双指针)

题目看起来很乱&#xff0c;实际上意思是&#xff1a;把数组中值不等于val的元素放在下标为0,1,2,3......&#xff0c;并且返回数组中值不等于val的元素的个数 方法一&#xff1a;直接判断覆盖 class Solution { public:int removeElement(vector<int>& nums, int…

【弹性计算】弹性裸金属服务器和神龙虚拟化(二):适用场景

弹性裸金属服务器和神龙虚拟化&#xff08;二&#xff09;&#xff1a;适用场景 1.混合云和第三方虚拟化软件部署2.高隔离容器部署3.高质量计算服务4.高速低时延 RDMA 网络支持场景5.RISC CPU 支持6.GPU 性能无损输出 公共云服务提供商推出 弹性裸金属服务器&#xff0c;很显然…

深入解析 Spring WebFlux:原理与应用

优质博文&#xff1a;IT-BLOG-CN WebFlux 是 Spring Framework 5 引入的一种响应式编程框架&#xff0c;和Spring MVC同级&#xff0c;旨在处理高并发和低延迟的非阻塞应用。这是一个支持反应式编程模型的新Web框架体系。 顺便一提&#xff0c;Spring Cloud Gateway在实现上是…

命名管道的实现与共享内存介绍

1.命名管道实现 comm.hpp文件 1.定义宏 通过宏来简便代码中&#xff0c;判断错误用宏就可以少写代码。 #define ERR_EXIT(m) \do \{ \perror(m); \exit(EXIT_FAILURE); \} while (0)在宏定义中使用 do { ... …

Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)

文章目录 Redis下载地址&#xff1a;一、zip压缩包方式下载安装 1、下载Redis压缩包2、解压到文件夹3、启动Redis服务4、打开Redis客户端进行连接5、使用一些基础操作来测试 二、msi安装包方式下载安装 1、下载Redis安装包2、进行安装3、进行配置4、启动服务5、测试能否正常工…

哔哩哔哩IT私塾python爬虫视频教程中的项目文件

视频链接&#xff1a; Python课程天花板,Python入门Python爬虫Python数据分析5天项目实操/Python基础.Python教程_哔哩哔哩_bilibili 视频教程中要访问的链接&#xff1a; 豆瓣电影 Top 250 httpbin.org seo推广公司网站模板_站长素材 Examples - Apache ECharts WordCloud…

go前后端开源项目go-admin,本地启动

https://github.com/go-admin-team/go-admin 教程 1.拉取项目 git clone https://github.com/go-admin-team/go-admin.git 2.更新整理依赖 go mod tidy会整理依赖&#xff0c;下载缺少的包&#xff0c;移除不用的&#xff0c;并更新go.sum。 # 更新整理依赖 go mod tidy 3.编…

深入理解Spring @Async:异步编程的利器与实战指南

一、为什么需要异步编程&#xff1f; 在现代高并发系统中&#xff0c;同步阻塞式编程会带来两大核心问题&#xff1a; // 同步处理示例 public void processOrder(Order order) {// 1. 保存订单&#xff08;耗时50ms&#xff09;orderRepository.save(order); // 2. 发送短信…

PHP:IDEA开发工具配置XDebug,断点调试

文章目录 一、php.ini配置二、IDEA配置 一、php.ini配置 [xdebug] zend_extension"F:\wamp64\bin\php\php7.4.0\ext\php_xdebug-2.8.0-7.4-vc15-x86_64.dll" xdebug.remote_enable on xdebug.remote_host 127.0.0.1 xdebug.remote_port 9001 xdebug.idekey"…

FPGA开发,使用Deepseek V3还是R1(9):FPGA的全流程(详细版)

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…