LeetCode_2_中等_两数相加

文章目录

  • 1. 题目
  • 2. 思路及代码实现(Python)
    • 2.1 模拟迭代
    • 2.2 递归


1. 题目

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

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

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9->9->9->9->9->9->9], l2 = [9->9->9->9]
输出:[8->9->9->9->0->0->0->1]


提示

  • 每个链表中的节点数在范围 [1, 100] 内
  • 节点处的值的取值范围 0 <= N o d e . v a l Node.val Node.val<= 9
  • 题目数据保证列表表示的数字不含前导零

2. 思路及代码实现(Python)

题解来源:力扣官方题解

2.1 模拟迭代

由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。

同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为 n 1 , n 2 n1,n2 n1,n2,进位值为 carry \textit{carry} carry,则它们的和为 n 1 + n 2 + carry n1+n2+\textit{carry} n1+n2+carry;其中,答案链表处相应位置的数字为 ( n 1 + n 2 + carry ) m o d 10 (n1+n2+\textit{carry}) \bmod 10 (n1+n2+carry)mod10,而新的进位值为 ⌊ n 1 + n 2 + carry 10 ⌋ \lfloor\frac{n1+n2+\textit{carry}}{10}\rfloor 10n1+n2+carry

如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 000 。此外,如果链表遍历结束后,有 carry > 0 \textit{carry} > 0 carry>0,还需要在答案链表的后面附加一个节点,节点的值为 carry \textit{carry} carry

需要遍历的次数为两个链表中的较长值,时间复杂度为 O ( m a x ( m , n ) ) O(max(m,n)) O(max(m,n)) m , n m,n m,n分别为两个链表的长度,而空间复杂度为 O ( 1 ) O(1) O(1),不随着链表长度而增加内存占用。

from typing import Optionalclass ListNode:def __init__(self, value=0, next=None):self.val = valueself.next = nextdef print_linked_list(head):current = headwhile current:print(current.val, end=" ")current = current.next

在下面的代码中,创建了一个 cur = dummy = ListNode() 对象,其中 cur 用来不断迭代指向链表的下一个节点,而 dummy 作为哨兵节点,仅标记着最一开始的 ListNode() 对象,因此最后返回的 dummy.next 是结果链表的头节点。

class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:cur = dummy = ListNode()carry = 0                           # 初始进位为0while l1 or l2 or carry:            # 只要链表不空,就继续迭代carry += (l1.val if l1 else 0) + (l2.val if l2 else 0)cur.next = ListNode(carry % 10) # 指向下一个节点carry //= 10                    # 更新进位cur = cur.next                  # 将指针移到下一个节点if l1: l1 = l1.next             # l1 不空则移到下一个节点,为空则在上面会取0if l2: l2 = l2.nextreturn dummy.next                   # 哨兵节点

示例:

node4 = ListNode(4)
node3 = ListNode(3, node4)
node2 = ListNode(2, node3)
node1 = ListNode(1, node2)node44 = ListNode(7)
node33 = ListNode(3, node44)
node22 = ListNode(2, node33)
node11 = ListNode(2, node22)res = Solution().addTwoNumbers(node1, node11)
print(print_linked_list(res))
3 4 6 1 1 None

执行用时:52 ms
消耗内存:17.11 MB

2.2 递归

如上述的迭代,我们很容易发现,从两个链表的头节点出发,按位计算操作都是类似的,都是进位加上 n 1 + n 2 n1+n2 n1+n2,与10的余数作为相加后的结果,与10的商(地板除法)作为新的进位 c a r r y carry carry,这可以理解为一个递归问题。

有个注意的点是,在递归时为了简化代码,需基于较长的链表进行递归,但不需要把链表的数都取出来,只需要在递归过程中,当某一链表的下一节点为空时(链表的节点取完了),即为较短链表,交换两个链表的标签即可。

递归的最底部是当两个链表都为空时,此时如果 c a r r y carry carry 如果不为空,则创建一个值为 c a r r y carry carry 的节点,反之,则为 None,时间复杂度为 O ( m a x ( m , n ) ) O(max(m,n)) O(max(m,n)),取决于较长链表的长度,而由于递归需要存储栈,空间复杂度也为 O ( m a x ( m , n ) ) O(max(m,n)) O(max(m,n)),栈深也取决于较长的链表长度。

class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode], carry=0) -> Optional[ListNode]:if l1 is None and l2 is None:                   # 递归边界:l1 和 l2 都是空节点return ListNode(carry) if carry else None   # 如果进位了,就额外创建一个节点if l1 is None:  l1, l2 = l2, l1carry += l1.val + (l2.val if l2 else 0)l1.val = carry % 10l1.next = self.addTwoNumbers(l1.next, l2.next if l2 else None, carry // 10)return l1

执行用时:52 ms
消耗内存:16.93 MB

参考题解:灵茶山艾府

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

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

相关文章

自定义异常相关问题及答案(2024)

1、为什么要使用自定义异常&#xff1f; 使用自定义异常&#xff08;Custom Exceptions&#xff09;在程序设计中是一个良好的实践&#xff0c;它有几个重要的好处&#xff1a; 提高代码可读性&#xff1a; 自定义异常的名称如果能清晰表达出异常的情况&#xff0c;那么阅读代…

4.将新对象的地址版给pveg变量:

string "pveg - now. Btrangt"Cabbage Heads Hone*): 1.为对象分配内存: 2. 请用类构造函数,它 为“Cabbnge Heads Hose 分配空间 - # "Cabbage Heads Hoe" 复制到分配的内存单元中 - #f "Cabbage Heads Howe" 的地址赋给str 将值19粒给1en 更…

vmware安装centos 7.6 操作系统

vmware安装centos 7.6 操作系统 1、下载centos 7.6 操作系统镜像文件2、安装centos 7.6操作系统3、配置centos 7.6 操作系统3.1、配置静态IP地址 和 dns3.2、查看磁盘分区3.3、查看系统版本 1、下载centos 7.6 操作系统镜像文件 这里选择 2018年10月发布的 7.6 版本 官方下载链…

vscode安装Prettier插件,对vue3项目进行格式化

之前vscode因为安装了Vue Language Features (Volar)插件&#xff0c;导致Prettier格式化失效&#xff0c;今天有空&#xff0c;又重新设置了一下 1. 插件要先安装上 2. 打开settings.json {"editor.defaultFormatter": "esbenp.prettier-vscode","…

【物联网】手把手完整实现STM32+ESP8266+MQTT+阿里云+APP应用——第3节-云产品流转配置

&#x1f31f;博主领域&#xff1a;嵌入式领域&人工智能&软件开发 本节目标&#xff1a;本节目标是进行云产品流转配置为后面实际的手机APP的接入做铺垫。云产品流转配置的目的是为了后面能够让后面实际做出来的手机APP可以控制STM32/MCU&#xff0c;STM32/MCU可以将数…

前缀和算法模板

一维前缀和 算法用途&#xff1a;快速求出数组中某一连续区间的和 一维前缀和算法模板 1、预处理出一个 dp 数组 要求原数组存储在 n 1 的空间大小中&#xff0c;其中后 n 个空间存数据。 dp数组&#xff0c;数组开 n 1个空间&#xff0c;dp[i] 表示 [ 1, i ] 区间内所有…

抖店如何高效率起店?从0到1的起店思路和心得,分享如下!

我是王路飞。 万事开头难&#xff0c;我为什么一直强调让新手商家先入门&#xff0c;把流程跑通呢&#xff1f; 就好像我们上学时候考试&#xff0c;都知道100分很难&#xff0c;那我们就先从60分开始好了&#xff0c;有了考60分的基础&#xff0c;你就知道你跟100分的差距在…

【Android】自定义View组件,并实现在 Compose、Kotlin、Xml 中调用

从事 Android 开发以来&#xff0c;很少有过自定义 View 的相关开发需求&#xff0c;大部分 UI 都是可以集成某些官方组件&#xff0c;在组件的基础上完成能够大大缩短开发时间。但今天我要讲的是&#xff1a;如何使用 Android 开发一个Compose、Xml都可以调用的组件&#xff1…

JavaScript异常处理详解

​​​​​​​一、异常的捕获 1.1 基本的try…catch语句 ES3开始引入了 try-catch 语句&#xff0c;是 JavaScript 中处理异常的标准方式。 语法&#xff1a; try{ //可能发生异常的代码 }catch(error){ //发生错误执行的代码 } 看下面的代码&#xff1a; <script>tr…

【深度学习程序实例】

以下是一个使用Python编写的深度学习程序实例&#xff0c;用于训练一个简单的神经网络来分类手写数字&#xff1a; import tensorflow as tf from tensorflow.keras.datasets import mnist# 加载MNIST数据集 (x_train, y_train), (x_test, y_test) mnist.load_data()# 数据预…

【.NET Core】异步编程模式

【.NET Core】异步编程模式 文章目录 【.NET Core】异步编程模式一、概述二、基于任务的异步模式&#xff08;TAP&#xff09;2.1 TAP模式命名、参数和返回类型2.2 TAP初始化异步操2.3 TAP如何编译2.4 手动生成TAP方法2.5 混合方法实现TAP2.6 TAP中Await挂起执行2.7 TAP中使用Y…

记一次canal除坑记录

记一次canal除坑记录 错误信息 Caused by :com.alibaba.otter.canal.parse.exception.CanalParseException: column size is not match for table 问题处理 今天对Canal相关程序进行升级&#xff0c;原监听的表及业务都正常&#xff1b;遇到新增加的表时总是不走&#xff1b;…

202402读书笔记|《当你老了》——灰蒙曙光比爱情温柔,清晨露珠比希望更可爱

202402读书笔记|《当你老了》——灰蒙曙光比爱情温柔&#xff0c;清晨露珠比希望更可爱 《当你老了》作者叶芝&#xff0c;断断续续碎片时间读完的一本书&#xff0c;不是很惊艳&#xff0c;但值得一读。就因为很喜欢当你老了&#xff0c;所以拾起的这本书。读完知道了原来叶芝…

什么是软件安全性测试?如何进行安全测试?

一、什么是软件安全性测试&#xff1f; 软件安全性测试是指对软件系统中的安全漏洞进行检测和评估的过程。其目的是为了确保软件系统在面对各种安全威胁时能够保持其功能的完整性、可用性和机密性。 二、软件安全性测试可以通过以下几个步骤来进行&#xff1a; 1. 需求分析&a…

[实践总结] 限制正则表达式匹配次数/时间 防止DoS攻击

思路 1、优化正则表达式 2、正则表达式无法优化的话&#xff0c;可以考虑限制匹配次数&#xff0c;或者限制匹配时间 限制 匹配次数 public class CountedCharSequence implements CharSequence {private final CharSequence charSequence;private long count;public Counte…

51单片机四位数码管计算器 Proteus仿真程序

目录 概要 仿真图 部分代码 资料下载地址&#xff1a;51单片机四位数码管计算器 Proteus仿真程序 概要 1.系统通过4x4的矩阵键盘输入数字及运算符。 2.可以进行4位十进制数以内的加法运算&#xff0c;如果计算结果超过4位十进制数&#xff0c;则屏幕显示E 3.可以进行加法以外…

LowB三人组(冒泡排序,插入排序,选择排序)(数据结构课设篇1,python版)(排序综合)

本章博客主要详细讲解一下LowB三人组排序&#xff0c;为什么叫LowB三人组呢&#xff1f;因为他们的时间复杂度都为O&#xff08;n^2&#xff09;。下篇博客会再讲解NB三人组&#xff08;堆排序&#xff0c;归并排序和快速排序&#xff09;&#xff0c;第三篇博客会讲解其他排序…

算法每日一题:队列中可以看到的人数 | 单调栈

大家好&#xff0c;我是星恒 今天是一道困难题&#xff0c;他的题解比较好理解&#xff0c;但是不好想出来&#xff0c;接下来就让我带大家来捋一捋这道题的思路&#xff0c;以及他有什么特征 题目&#xff1a;leetcode 1944有 n 个人排成一个队列&#xff0c;从左到右 编号为 …

Spring国际化的应用及原理详解

1. 简介 Spring国际化&#xff08;Spring Internationalization&#xff0c;简称i18n&#xff09;是Spring框架提供的一种机制&#xff0c;用于支持多语言的应用程序。它使得开发者能够轻松地在应用程序中实现不同语言的支持&#xff0c;从而满足全球化的需求。通过Spring国际…

面试必问究极重点之HashMap的底层原理

1.底层数据结构 JDK版本不同的数据结构 1.7 数组 链表 1.8 数组 &#xff08;链表 | 红黑树&#xff09; 2.添加数据put 在添加一个值的时候&#xff0c;首先会计算他的hash码&#xff0c;然后进行二次hash&#xff0c;在对当前长度取模得到在底层数组中的索引位置当取模完…