代码git:History for 2. 两数相加.py - WankkoRee/LeetCodeAnswersWithPython3
这题又是各种卡边缘条件的一题...
先是写个最基本的链表合并,然后简单地考虑一下进位。(assert False
只是我当调试断点用的,因为这题结果是对象,不太好直接检查,所以就下断点手动检查了)
# 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: ListNode, l2: ListNode) -> ListNode:
p = l1
q = l2
ex = 0
while p and q:
p.val += q.val + ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
p = p.next
q = q.next
if ex:
if p:
p.val += ex
else: # q
q.val += ex
return l1
solution = Solution()
a = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(3))), ListNode(5, ListNode(6, ListNode(4))))
assert False
结果自然是没过,数据是addTwoNumbers(ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9))))))), ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))
,因为进位的问题没考虑完全,即使有一条链表已经处理完了,只剩下单条链表,进位也可能不止一次,比如说这个9999999+9999
的情况,就需要在合并结束后连续进位,于是补一下结束后的连续进位,再看看正确率。
# 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: ListNode, l2: ListNode) -> ListNode:
p = l1
q = l2
ex = 0
while p and q:
p.val += q.val + ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
p = p.next
q = q.next
if ex:
if p:
while p:
p.val += ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
break
else: # q
while q:
q.val += ex
if q.val >= 10:
ex = 1
q.val -= 10
else:
break
return l1
solution = Solution()
a = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(3))), ListNode(5, ListNode(6, ListNode(4))))
b = solution.addTwoNumbers(ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9))))))), ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))
assert False
然后因为是没测直接交的,所以又在刚才的数据上翻车了,翻的原因是忘记写链表指针后移了...
# 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: ListNode, l2: ListNode) -> ListNode:
p = l1
q = l2
ex = 0
while p and q:
p.val += q.val + ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
p = p.next
q = q.next
if ex:
if p:
while p:
p.val += ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
break
p = p.next
else: # q
while q:
q.val += ex
if q.val >= 10:
ex = 1
q.val -= 10
else:
break
q = q.next
return l1
solution = Solution()
a = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(3))), ListNode(5, ListNode(6, ListNode(4))))
b = solution.addTwoNumbers(ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9))))))), ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))
assert False
然后又风风火火地交,风风火火地裂开,主要还是太自信了,最后没有处理进位导致溢出了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: ListNode, l2: ListNode) -> ListNode:
p = l1
q = l2
ex = 0
while p and q:
p.val += q.val + ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
p = p.next
q = q.next
if ex:
if p:
while p:
p.val += ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
break
p = p.next
if ex:
p.next = ListNode(ex)
else: # q
while q:
q.val += ex
if q.val >= 10:
ex = 1
q.val -= 10
else:
ex = 0
break
q = q.next
if ex:
q.next = ListNode(ex)
return l1
solution = Solution()
a = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(3))), ListNode(5, ListNode(6, ListNode(4))))
b = solution.addTwoNumbers(ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9))))))), ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))
assert False
结果就报错了,因为在处理最后的溢出进位时,p或者q已经是None
了,压根不是ListNode
对象...于是就把这处的处理上移一下,确保还没后移指针时先判断一下要不要处理。
# 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: ListNode, l2: ListNode) -> ListNode:
p = l1
q = l2
ex = 0
while p and q:
p.val += q.val + ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
p = p.next
q = q.next
if ex:
if p:
while p:
p.val += ex
if p.val >= 10:
ex = 1
p.val -= 10
if p.next:
p = p.next
else:
p.next = ListNode(ex)
break
else:
break
else: # q
while q:
q.val += ex
if q.val >= 10:
ex = 1
q.val -= 10
if q.next:
q = q.next
else:
q.next = ListNode(ex)
break
else:
break
return l1
solution = Solution()
a = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(3))), ListNode(5, ListNode(6, ListNode(4))))
b = solution.addTwoNumbers(ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9))))))), ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))
assert False
这个边缘数据总算过了,但是又来了个addTwoNumbers(ListNode(2, ListNode(4, ListNode(9))), ListNode(5, ListNode(6, ListNode(4, ListNode(9)))))
的边缘数据,这个纯属是刚才考虑q比p长的时候想岔了,忘记把q尾部数据接到p上面去了,不过既然拼接了链表的话,那就下面进位不用管q的事了,所有数据全在p上了。
# 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: ListNode, l2: ListNode) -> ListNode:
p = l1
q = l2
ex = 0
while True:
p.val += q.val + ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
if p.next:
p = p.next
else:
p.next = q.next
p = p.next
break
if q.next:
q = q.next
else:
break
if ex:
while p:
p.val += ex
if p.val >= 10:
ex = 1
p.val -= 10
if p.next:
p = p.next
else:
p.next = ListNode(ex)
break
else:
break
return l1
solution = Solution()
a = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(3))), ListNode(5, ListNode(6, ListNode(4))))
b = solution.addTwoNumbers(ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9))))))), ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))
c = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(9))), ListNode(5, ListNode(6, ListNode(4, ListNode(9)))))
assert False
然后又来个addTwoNumbers(ListNode(5), ListNode(5))
的边缘数据,这个的话是因为刚才改动的时候,数据判定的位置不太合理造成的,导致把p给整成None
了,所以把上面指针后移的判断给改改就行。
# 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: ListNode, l2: ListNode) -> ListNode:
p = l1
q = l2
ex = 0
while True:
p.val += q.val + ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
if p.next:
p = p.next
if q.next:
q = q.next
else:
break
else:
if q.next:
p.next = q.next
p = p.next
break
else:
if ex: # 特殊情况
p.next = ListNode(ex)
ex = 0
break
if ex:
while p:
p.val += ex
if p.val >= 10:
ex = 1
p.val -= 10
if p.next:
p = p.next
else:
p.next = ListNode(ex)
break
else:
break
return l1
solution = Solution()
a = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(3))), ListNode(5, ListNode(6, ListNode(4))))
b = solution.addTwoNumbers(ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9))))))), ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))
c = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(9))), ListNode(5, ListNode(6, ListNode(4, ListNode(9)))))
d = solution.addTwoNumbers(ListNode(5), ListNode(5))
assert False
结果这回一改连第一个数据都没过了,仔细看了下跳出情况发现not p.next and not q.next and not ex
的时候本来也得跳,结果整忘了,所以直接把not p.next and not q.next and ex
的break
给共享一下就完事。
# 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: ListNode, l2: ListNode) -> ListNode:
p = l1
q = l2
ex = 0
while True:
p.val += q.val + ex
if p.val >= 10:
ex = 1
p.val -= 10
else:
ex = 0
if p.next:
p = p.next
if q.next:
q = q.next
else:
break
else:
if q.next:
p.next = q.next
p = p.next
break
else:
if ex: # 特殊情况
p.next = ListNode(ex)
ex = 0
break
if ex:
while p:
p.val += ex
if p.val >= 10:
ex = 1
p.val -= 10
if p.next:
p = p.next
else:
p.next = ListNode(ex)
break
else:
break
return l1
solution = Solution()
a = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(3))), ListNode(5, ListNode(6, ListNode(4))))
b = solution.addTwoNumbers(ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9))))))), ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))
c = solution.addTwoNumbers(ListNode(2, ListNode(4, ListNode(9))), ListNode(5, ListNode(6, ListNode(4, ListNode(9)))))
d = solution.addTwoNumbers(ListNode(5), ListNode(5))
assert False
终于过了,这测试数据仔细得有点离谱。
执行用时:
40 ms
, 在所有Python3
提交中击败了99.45%
的用户
内存消耗:15.1 MB
, 在所有Python3
提交中击败了22.40%
的用户
通过测试用例:1568 / 1568