两数相加
在讲解之前,要知道的:python没有专门的指针的概念,在python中每个变量都是指针。
-
我的想法:查看或计算出每个链表的长度,然后通过做 1 0 n 10^n 10n运算,还原出这两个十进制数,然后进行相加,再求出结果的各个位后保存起来,进行输出操作。
-
提示:无需将原来的十进制数还原出来,而是直接在两个链表身上做运算!因为被来就是逆序存放的,所以每个链表中的第一个元素都是个位,第二个元素都是十位,以此类推。所以可以直接让其进行运算~
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
# 你可以实现一些链表的增删等操作
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
result = ListNode(0) # result是一个头指针,将其数据初始化为了0
r = result # r总是指向返回结果的链表的新元素
carry = 0 # carry表示进位
# 循环进行对应位相加
while(l1 or l2):
x = (l1.val if l1 else 0) # 如果l1有数据,则x为该数据,否则为0
y = (l2.val if l2 else 0) # 如果l2有数据,则y为该数据,否则为0
s = carry + x + y
carry = s // 10 # 得到进位(0或1)
r.next = ListNode(s % 10) # 新建一个节点,并保存该位的运算结果
r = r.next # r与r.next将指向同一个内存地址
# 将“指针”向后移动
if l1 != None:
l1 = l1.next
if l2 != None :
l2 = l2.next
# 判断最高位相加后是否有进位,有进位则新建一个节点保存进位‘1’
if(carry > 0):
r.next = ListNode(1)
return result.next # 注意:这里返回的是result.next,而不是result。因为result是头指针,没有真正保存有效的数据
num1 = ListNode(2)
num1.next = ListNode(4)
num1.next.next = ListNode(3)
num2 = ListNode(5)
num2.next = ListNode(6)
num2.next.next = ListNode(4)
solution = Solution()
result = solution.addTwoNumbers(num1, num2)
print(result.val, result.next.val, result.next.next.val)
- 时间复杂度:
O(max(m, n))
假设 m m m 和 n n n 分别表示 l 1 l1 l1 和 l 2 l2 l2 的长度,上面的算法最多重复 m a x ( m , n ) max(m, n) max(m,n)次。- 空间复杂度:
O(max(m, n))
新列表的长度最多为 O ( m a x ( m , n ) ) + 1 O(max(m, n)) + 1 O(max(m,n))+1 。
拓展:实际上,题目中说“逆序”存放,使题目变得简单了;如果不是逆序存放,而是正序存放在链表中呢?例如:
那就不能直接让两个链表中的对应位相加了,因为两数可能不是同一数量级的!在这种情况下,才更应该使用我上面那道题的“我的想法”。比如,可以把链表中的数据全部取出来,放到一个列表中,然后将其转换位对应的十进制,然后进行相加就可以了。最后再把结果存放到一个链表中就大功告成。