两数相加 - 模拟+递归

两数相加原题地址

方法一:模拟

注意到链表的方向是从低位到高位,而做“竖式相加”也是低位到高位。

   1 2 3

+    4 5

-----------

   1 6 8

所以可以用同样的方法来模拟。如果不考虑进位,只需要取出对应位的2个数相加,再尾插到新的链表中。

注意新的链表也是从低位到高位,也就是按照8->6->1的方向存储。链表中不存在前置0,所以当其中一个链表遍历完了,另一个链表没遍历完的时候,遍历完的链表剩下的元素都当做前置0来处理。

实际计算时,还会出现进位的情况,所以需要一个变量carry来存储进位值,这个变量要定义在循环外面,因为下一次进入循环后不能销毁,计算时需要加上进位值。最终需要存储在新链表的元素就是(n1+n2+carry)mod10。其中n1和n2为两个链表中取出来的值,如果其中一个链表走到头了当做前置0处理。另外,新的进位值为(n1+n2+carry)/10。

需要注意尾插时对于新链表是否为空的分类讨论。如果新链表为空,需要对头结点重新赋值,否则直接在尾部插入即可。为了防止尾插时的找尾操作效率太低,最好定义一个尾指针存储尾部的节点地址。

最后一次循环走完后,如果carry不为0,记得还需在尾部插入一个1,这点非常容易出错。

// 方法一:模拟
class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {// 由于要反复尾插,最好定义一个指针存储尾节点的地址ListNode* head = nullptr, * tail = nullptr;int carry = 0; // 进位,必须定义在循环外面,下次循环还能用// 两条链表都走完才结束while (l1 || l2){// 如果链表走完了,剩下的数为前置0// 1 <- 2 <- 3 <- 4 <- 5// 0 <- 0 <- 6 <- 7 <- 8int n1 = l1 ? l1->val : 0;int n2 = l2 ? l2->val : 0;int sum = n1 + n2 + carry;carry = sum / 10;// 尾插,是否为空链表要分类讨论if (!head){head = tail = new ListNode(sum % 10);}else{tail->next = new ListNode(sum % 10);tail = tail->next;}if (l1){l1 = l1->next;}if (l2){l2 = l2->next;}}if (carry){tail->next = new ListNode(1);}return head;}
};

方法二:递归

对于链表的题目,自然会想到递归。根据模拟法的思路,影响插入元素的因素为两个链表取出来的值以及进位值,及(l1, l2, carry)。如果要改为递归实现,我们需要把问题转换为:当前需要插入的值(n1+n2+carry)mod10,以及子问题(当前需要插入的值后面需要插入什么呢?)

子问题的解决很简单,只需要在当前节点后面插入由子问题(l1的下一个节点, l2的下一个节点, carry)构成的链表。这么说有点抽象,看图:

递归结束的条件是什么呢?自然是两个链表都走完了,而且没有进位。

// 方法二:递归
class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {return _addTwoNumbers(l1, l2, 0);}ListNode* _addTwoNumbers(ListNode* l1, ListNode* l2, int carry){// 链表都为空且无进位,终止递归if (!l1 && !l2 && carry == 0){return nullptr;}// 链表非空,则取值相加int n1 = 0;int n2 = 0;if (l1){n1 = l1->val;l1 = l1->next;}if (l2){n2 = l2->val;l2 = l2->next;}int sum = n1 + n2 + carry;carry = sum / 10;// 链接上新的节点,继续递归至下一层ListNode* node = new ListNode(sum % 10);node->next = _addTwoNumbers(l1, l2, carry);return node;}
};

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

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

相关文章

作业2024/2/3

第二章 引用内联重载 一&#xff0e;选择题 1、适宜采用inline定义函数情况是&#xff08;C&#xff09; A. 函数体含有循环语句 B. 函数体含有递归语句 C. 函数代码少、频繁调用 D. 函数代码多、不常调用 2、假定一个函数为A(int i4, int j0) {;}, 则执行“A (1);”语句…

酷开系统 | 酷开科技智慧AI带你领略神奇的世界

在这个科技日新月异的时代&#xff0c;AI已成为我们生活中不可或缺的一部分。它不仅改变了我们的生活方式&#xff0c;更让我们对未来充满期待。说起酷开系统中智慧AI的强大&#xff0c;着实让人叹为观止。无论是语音识别、数据整理还是语言处理&#xff0c;智慧AI都在不断地突…

本次安装Visual Studio 所用的安装程序不完整。请重新运行VisualStudio安装程序以解决此问题

今天点开VS的时候遇到了这个问题 因为昨天升级到一半电脑关机了&#xff0c;今天打开软件遇到如下错误&#xff0c; 解决办法很简单&#xff0c;找到安装目录进入Installer文件夹 我的目录在C:\Program Files (x86)\Microsoft Visual Studio\Installer 找到vs_installer.exe…

【Springcloud篇】学习笔记六(十一、十二章):Config分布式配置中心、Bus消息总线

第十一章_Config分布式配置中心 1.Config分布式配置中心介绍 1.1分布式系统面临的配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务&#xff0c;每个服务的粒度相对较小&#xff0c;因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行&…

【C++入门到精通】C++的IO流(输入输出流) [ C++入门 ]

阅读导航 引言一、C语言的输入与输出二、流是什么三、CIO流1. C标准IO流&#xff08;1&#xff09;istream&#xff08;2&#xff09;ostream&#xff08;3&#xff09;iostream&#xff08;4&#xff09;cin 和 cout 2. C文件IO流&#xff08;1&#xff09;ifstream&#xff0…

苹果的ipad可能会缓存vue项目的数据或者pinia数据

如果你发现开发的vue项目在ipad上出现了异常&#xff0c;比如数据出现NaN的情况&#xff0c;或者computed计算属性没生效&#xff0c;或者pinia里面的数据没生效&#xff0c;可能就是ipad浏览器safari缓存了数据导致的&#xff0c;只需要清空safari里面缓存的数据就可以了&…

日志追踪-Tracing

1. 前言 分布式链路跟踪中有两个重要的概念&#xff1a;跟踪&#xff08;trace&#xff09;和 跨度&#xff08; span)。trace 是请求在分布式系统中的整个链路视图&#xff0c;span 则代表整个链路中不同服务内部的视图&#xff0c;span 组合在一起就是整个 trace 的视图在整个…

MacBook Pro (15 英寸,2018) 本地体验运行 6B 大模型

接上篇 在 Mac 上加速 PyTorch 训练&#xff0c;准备完 MPS 环境之后&#xff0c;开始在本地体验 ChatGLM3-6B 模型。 一、下载本仓库&#xff1a; (base) markvivvMBP dev % git clone https://github.com/THUDM/ChatGLM3Cloning into ChatGLM3... remote: Enumerating obje…

C++并发编程 -2.线程间共享数据

本章就以在C中进行安全的数据共享为主题。避免上述及其他潜在问题的发生的同时&#xff0c;将共享数据的优势发挥到最大。 一. 锁分类和使用 按照用途分为互斥、递归、读写、自旋、条件变量。本章节着重介绍前四种&#xff0c;条件变量后续章节单独介绍。 由于锁无法进行拷贝…

数字孪生产品评测:五款数字孪生产品的优劣对比

作为数据可视化领域的资深用户&#xff0c;我深知数字孪生产品在当今工业4.0时代的重要地位。本文将为大家介绍五款市面上的数字孪生产品&#xff0c;帮助大家了解各产品之间的优缺点&#xff0c;选择适合自己的产品。 一、山海鲸可视化 山海鲸可视化是一款强大而灵活的免费数…

npm install一直报错 failed, reason: certificate has expired

刚开始我以为是taobao镜像源的问题&#xff0c;所以我把npm的地址切换成了 https://resgistry.npmjs.org/ &#xff0c;发现还是不行。 问题解决&#xff1a; npm config set strict-ssl false 执行上面命令之后&#xff0c;npm install 成功

C# 读取文件中的配置信息

文章目录 定义使用文件格式代码 C#读取文件并处理&#xff1b;C# 读取文件中的配置信息。 在有的程序中&#xff0c;需要从本地文件中读取配置信息&#xff0c;以进行初始化。 定义 定义一个静态函数来获取文件信息。StreamReader 类。 /// <summary> /// 读取参数文件…