LeetCode Python 链表指针 两数相加

Leetcode-链表指针-两数相加

#
# @lc app=leetcode.cn id=2 lang=python3
#
# [2] 两数相加
#
# https://leetcode-cn.com/problems/add-two-numbers/description/
#
# algorithms
# Medium (36.02%)
# Likes:    3415
# Dislikes: 0
# Total Accepted:    256.8K
# Total Submissions: 712.9K
# Testcase Example:  '[2,4,3]\n[5,6,4]'
#
# 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
# 
# 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
# 
# 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
# 
# 示例:
# 
# 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
# 输出:7 -> 0 -> 8
# 原因:342 + 465 = 807
# 
# 
#

思路

请特别注意以下情况:

复杂度分析

时间复杂度:$O(\max(m, n))$,假设 m 和 n 分别表示 $l1$$l2$ 的长度,上面的算法最多重复 $max(m,n)$ 次。

空间复杂度:$O(\max(m, n))$, 新列表的长度最多为 $max(m,n)+1$

特别注意

image.png

伪代码

详见leetcode

结果

Accepted
1563/1563 cases passed (68 ms)
Your runtime beats 99.44 % of python3 submissions
Your memory usage beats 5.06 % of python3 submissions (14 MB)

时间复杂度O(N)

空间复杂度O(N)

空间复杂度仍然有优化空间,可以将计算结果存至l1中。但最差情况复杂度任然为O(N)

Code

# @lc code=start
# 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:
        head=ListNode(0)
        p = ListNode(0)
        #q = ListNode(0)

        f_carry = False
        first = True

        while(l1!=None and l2!=None):
            if first:
                newNode = ListNode(0)
                p.next = newNode
                head.next = newNode
                first = False
            else:
                newNode = ListNode(0)
                p.next.next = newNode
                p.next = newNode

            if f_carry:
                tmp=l1.val+l2.val+1
                f_carry=False
            else:
                tmp=l1.val+l2.val
            
            if tmp>=10:
                p.next.val=tmp-10
                f_carry = True
            else:
                p.next.val =tmp

            l1 = l1.next
            l2 = l2.next
        
            #接上
        if l1!=None:
            p.next.next = l1

        if l2!=None:
            p.next.next = l2


        while f_carry: #向前进一位
            if p.next.next != None:
                p.next = p.next.next
            else:
                p.next.next = ListNode(1)
                break

            if p.next.val ==9:
                p.next.val = 0
            else:
                p.next.val= 1+p.next.val
                f_carry=False
        
        return head.next
        



# @lc code=end