源代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
class ListNode(object):
def __init__(self,val=None):
self.val = val
self.next = None
class ListNode_handle: # 定义单链表的各种操作
def __init__(self):
self.cur_node = None
# self.nodelist=None # 用来保存结果的链表,方法3?????
def add(self, data): # 头插法(每次添加新节点都是在首节点之后添加)
node = ListNode()
node.val = data
node.next = self.cur_node
self.cur_node = node # cur_node总是指向新节点
return node
def print_ListNode(self, node):
while node: # 当条件变成node.val时可能报错,最后一个元素可能是空节点,它没有数据域和指针域
# print ('\nnode: ', node, ' value: ', node.val, ' next: ', node.next)
print(node.val)
node = node.next
def get_list(self, nodelist): # 能否实现利用for 循环快速遍历
list = []
while nodelist:
list.append(nodelist.val)
nodelist = nodelist.next
return list
def __next__(self,node):
# 奇思妙想:就是要遍历当前node节点后所有的元素
pass
class Solution(object):
def addTwoNumbers(self, l1, l2):
carry = 0
result_handle = ListNode_handle()
result = ListNode()
while l1 != None or l2 != None:
if not carry: # 无进位
if l1 != None and l2 != None:
l3_val = l1.val + l2.val
elif l1 == None and l2 != None:
l3_val = l2.val
elif l1 != None and l2 == None:
l3_val = l1.val
else:
pass
else: # 有进位
if l1 != None and l2 != None:
l3_val = l1.val + l2.val + 1
elif l1 == None and l2 != None:
l3_val = l2.val + 1
elif l1 != None and l2 == None:
l3_val = l1.val + 1
else:
pass
carry = 0 # 处理完进位后,将进位标志置空
if l3_val < 10:
result = result_handle.add(l3_val)
else:
result = result_handle.add(l3_val % 10)
carry = l3_val // 10
try:
l1 = l1.next
except:
pass
try:
l2 = l2.next # l2 为None,执行except语句
except:
pass
if carry:
result = result_handle.add(carry)
# result_handle.print_ListNode(result)
return result
class Solution1:
# @return a ListNode
def addTwoNumbers(self, l1, l2):
carry = 0
root = n = ListNode('prior') # root 始终指向第一个头结点,n节点则是指向新加入的节点
while l1 or l2 or carry: # 防止l1 or l2 为空链表
v1 = v2 = 0
if l1:
v1 = l1.val
l1 = l1.next
if l2:
v2 = l2.val
l2 = l2.next
carry, val = divmod(v1 + v2 + carry, 10)
n.next = ListNode(val) # 尾插法添加新节点
n = n.next
return root.next # 结果时逆序的
if __name__ == "__main__":
ListNode_1 = ListNode_handle()
l1 = ListNode()
l1_list = [9,9]
# 利用不同的ListNode_handle类进行处理,
# 因为使用头插法插入节点,正好每个节点都是倒序链接起来,方便了遍历链表结算每位数的相加
for i in l1_list:
l1 = ListNode_1.add(i)
ListNode_2 = ListNode_handle()
l2 = ListNode()
l2_list = [1]
for i in l2_list:
l2 = ListNode_2.add(i)
# result = Solution().addTwoNumbers(l1, l2)
# result1_node1 = ListNode_handle()
# des=result1_node1.get_list(result)
# 方法2 构建
result1 = Solution1().addTwoNumbers(l1, l2)
result1_node = ListNode_handle()
des=result1_node.get_list(result1)
print(des[::-1])
程序的难点
- 两数相加考虑进位
- 遍历链表,将结果如何串起来
Q&A
-
每每创建新节点,头结点,首元节点用来干嘛
答:首元节点顾名思义,加入头结点方便添加节点 -
每次我在.next和=操作上会犯迷糊
答:.next 就是把链接 链表下一个元素, =赋值符号 -
any能不能判断空链表是否为空?(或许未来添加for循环调用的next和iter 魔术方法就可以实现)
答:TypeError: ‘ListNode1’ object is not iterable(可以使用序列化工具对其序列化) -
如何处理首位多了1位数 的问题例如99+1=100
答:两位数相乘可能有进位为2, so 两位数相加会不会进位超过2 呢 -
程序的架构并不好
答: 按照数据结构中对单链表的抽象数据类型, 定义应该包括节点的定义和相关操作的定义
答2: 能不能自定义数据结构,使之能够和容器类型一致,eg. 可以直接使用 for 循环遍历(__ iter __魔术方法,该方法需要返回迭代器iterator) -
result 和result_handle的联系
答; result_handle 初始化一个空数据的头结点,通过类的add方法往链表中添加节点,并返回新加入的节点result -
divmod(12,10)=>1,2==>提取进位和余数