目录
力扣算法刷题:2.两数相加
前言:博主也仅仅是在学习过程之中,如果有写的不好的地方,望海涵!
1.题目
点击此处跳转力扣原题页面
给你两个
非空
的链表,表示两个非负的整数。它们每位数字都是按照逆序
的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
输入: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]
题目实例代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
题目剖析
题目要求:
给定两个逆序链表表示的整数,返回它们相加后的逆序链表。
给定条件:
- 链表非空
- 逆序存储
未给定条件:
- 是否两个链表长度相同===>显然是要考虑的
逆序存储,所以链表的头为个位数字。
题目给定示例代码的解析
这段代码 Definition for singly-linked list.本质是定义节点类,这个节点类的数据域和指针域,可以直接赋予,与博主之前的讲解单向链表不相同,博主专门定义了一个链表类,来操作链表。
思路
先看题目中的案例数据:
- 初始化结果链表的虚拟头节点
dummyHead
,以及进位carry
为 0。 - 初始化指针
current
指向dummyHead
,用于构建结果链表。 - 遍历两个输入链表
list1
和list2
:- 分别获取当前节点的值
val1
和val2
,若为空则取值为 0。 - 计算当前位的和
total = val1 + val2 + carry
,以及新的进位carry = total // 10
。 - 创建新节点,值为
total % 10
,将其连接到结果链表中。 - 将指针
current
移动到下一个节点。 - 若
list1
不为空,则将list1
指针移动到下一个节点。 - 若
list2
不为空,则将list2
指针移动到下一个节点。
- 分别获取当前节点的值
- 若最后还有进位
carry
,创建新节点,值为carry
,将其连接到结果链表中。 - 返回结果链表的头节点,即
dummyHead.next
。
伪代码:
函数 addTwoNumbers(l1, l2):
初始化 res = 新建节点() # 创建一个尾节点
初始化 pointer = res # 实际的指针,指向准备添加值的位置,next 不会覆盖最开始的值 0
初始化 jinwei = 0
当 l1 非空 或者 l2 非空 或者 jinwei 非 0 时循环:
初始化 p1 = 若 l1 非空,则取 l1 的值,否则为 0
初始化 p2 = 若 l2 非空,则取 l2 的值,否则为 0
初始化 total = p1 + p2 + jinwei # 计算和 如果大于等于 10 就需要进位
设置 jinwei = total 除以 10 # 进行进位
创建一个新节点,值为 total 除以 10 的余数,并将其设置为 pointer 的下一个节点 # 一开始就从 next 属性开始,不会改变 res.val 的值
设置 pointer 的下一个节点为新节点
将 pointer 移动到下一个节点
若 l1 非空: # 只要当前的节点有值 就直接进行下一节点,也不用管有没有值
将 l1 移动到下一个节点
若 l2 非空:
将 l2 移动到下一个节点
返回 res 的下一个节点
代码实现:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
res = ListNode() # 创建一个尾节点
pointer =res # 实际的指针,指向准备添加值的位置,next不会覆盖最开始的值0
jinwei = 0
while l1 or l2 or jinwei :
p1 = l1.val if l1 else 0
p2 = l2.val if l2 else 0
sum = p1+p2+jinwei # 计算和 如果大于等于10 就需要进位
jinwei = sum//10 # 进行进位
pointer.next = ListNode(sum % 10) # 一开始就从next属性开始,不会改变res.val的值
pointer = pointer.next
if l1: # 只要当前的节点有值 就直接进行下一节点,也不用管有没有值
l1 = l1.next
if l2:
l2 = l2.next
return res.next
最后res的结果如图所示(案例1)
画框的地方为题目的结果!!!
故最后输出res.next