Skip to content

Latest commit

 

History

History
40 lines (33 loc) · 1.75 KB

File metadata and controls

40 lines (33 loc) · 1.75 KB

基本思路

逆序存储很友好了,直接遍历链表就是从个位开始的,符合我们计算加法的习惯顺序。如果是正序存储,那倒要费点脑筋了,可能需要 翻转链表 或者使用栈来辅助。

这道题主要考察 链表双指针技巧 和加法运算过程中对进位的处理。注意这个 carry 变量的处理,在我们手动模拟加法过程的时候会经常用到。

代码中还用到一个链表的算法题中是很常见的「虚拟头结点」技巧,也就是 dummy 节点。你可以试试,如果不使用 dummy 虚拟节点,代码会稍显复杂,而有了 dummy 节点这个占位符,可以避免处理初始的空指针情况,降低代码的复杂性。

双指针

class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        p1, p2 = l1, l2
        # 虚拟头结点(构建新链表时的常用技巧)
        dummy = ListNode(-1)
        p = dummy

        # 记录进位
        carry = 0
        # 两条链表走完且没有进位时才能结束循环
        # 注意即使p1和p2空指针的情况下carry也可能进位!
        while p1 or p2 or carry:
            # 注意p1和p2都有可能空指针
            cur1 = p1.val if p1 else 0
            cur2 = p2.val if p2 else 0
            res = cur1 + cur2 + carry

            # 注意先计算carry再计算res
            carry = res // 10
            res %= 10

            # 构建新节点
            p.next = ListNode(res)
            # 注意p1和p2到空指针的情况下就不要再前进了
            p1, p2, p = p1.next if p1 else None, p2.next if p2 else None, p.next

        # 返回结果链表的头结点(去除虚拟头结点)
        return dummy.next