链表两数相和 (2)--Leetcode

本文深入探讨了使用链表表示的非负整数加法问题,详细解释了如何处理不同长度链表的相加,包括进位管理和链表节点为None的情况。通过隐形复制链表的方法,提供了一个完整的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

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

转自:力扣(LeetCode)

题目分析:

根据题目,我们要复习关于链表的基础知识,链表作为数据结构的基本
非线性数据结构,主要有数据(val)和指针(next)构成,我们可以再python中
用类来定义一个基础的链表结构:

通过类定义一个初始状态为NoneNoneNone的数据节点:

class ListNode():
	def __init__(self,x):
		self.val=x
		self.next=None

在定义完链表的数据结构后,我们可以开始解题:我们要考虑如下几个问题:

  1. 如何高效的解决相加数字的位数问题?例如三位数和二位数相加.
  2. 如何解决进位问题
  3. 如何解决链表节点为None 报错问题

我们从解决以上三个问题来展开我们的论述:

问题解决

位数问题:

开始时考虑通过判断语句来分别构建不同位数情况,但是无论什么情况下,用到判断语句会让情况变得复杂,让代码变得冗长无效,所以我们考虑用循环语句来解决位数问题,两数相加,我们无论如何都会加到最高位,较低位数字在高位置0:通过如下代码表示我们需要表示的含义:

#l1,l2是含有不同节点的链表
while(l1 or l2):  #这句代码的意思是,循环到l1,l2的最高位
	x=l1.val if l1 else 0
	y=l2.val if l2 else 0  #这里我为什么要以l1和l2为判断条件呢?
	#因为我上面提到的第三个问题,如果链表节点为None的话,我们直接
	#调用链表的属性会报错,所以链表的判断中,我们需要以它本身而不是
	#它的属性来判断,避免出错
	if (l1!=None):
		l1=l1.next
	if(l2!=None):
		l2=l2.next

进位问题

我们用carrycarrycarry来表示进位,通过//////整数除法来确定carry的值,因此我们在上面的基础加入进位:

carry=0
a=ListNode(0)
while(l1 or l2):
	x=l1.val if l1 else 0
	y=l2.val if l2 else 0 
	res=x+y+carry
	s=ListNode(res%10)
	a.next=s
	carry=res//10
	if (l1!=None):
		l1=l1.next
	if(l2!=None):
		l2=l2.next
	a=a.next

进一步考虑

如果发生最高位进位的情况会怎么样呢?我们需要在之前的代码上加上一个判断条件,如果最后一次进位不为0,我们就需要在所求链表的尾部加入进位值 。

if carry!=0:
	a.next=ListNode(carry)

但是这时候还会发生一个问题,我们的结果链表aaa在一边遍历一遍赋值.等赋值完后,链表已经到了表尾,这时候返回的链表不是我们需要的,我们需要通过隐形复制链表BBB来让链表BBB充当边赋值边遍历的过程,我们通过返回被复制的链表作为我们的结果。

完整代码

# Definition for singly-linked list.
class ListNode(object):
     def __init__(self, x):
         self.val = x
         self.next = None

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        s=ListNode(0)
        a=s
        carry=0
        while(l1 or l2):
            x=l1.val if l1 else 0  #当它跳到val的时候,如果l为节点且为空的话 就会报错
            y=l2.val if l2 else 0
            res=ListNode((x+y+carry)%10)
            a.next=res
            carry=(x+y+carry)//10  #整数除法
            a=a.next
            if (l1!=None):
                l1=l1.next
            if  (l2!=None):
                l2=l2.next
        if carry!=0:
            a.next=ListNode(1)
        return s.next        

总结

  1. 因为我们定义的默认next=None,所以链表要用节点来判断,因为节点要么位None 要么为class ,不要用节点的属性来判断,当节点为None时,用属性判断会报错。
  2. .然后这个是常规的位数相加问题,只不过套上了链表的外皮,但是本质是一样,是进位和相应位数的数字相加,我们需要考虑多种情况,例如最高位进位的问题,不同位数的问题。
  3. 一个隐形复制的问题也比较有趣,我们让a=sa=sa=s,然后让aaa代替sss边遍历边复制,a的值也会相应的复制到s,也就是所谓的隐形复制,复制的值变也为导致被复制的值变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值