Python - 两数相加 (有链表 无链表)

news/2025/2/22 19:59:42

一.引言

给定两个 非空 的列表,表示两个非负的整数。它们每位数字都是按照 顺序 的方式存储的,并且每个节点只能存储 一位 数字。请将两个数相加并返回结果。

Tips: 两个数字均不会以0为开头

示例:

nums1 = [1,2,3]

nums2 = [2,3,4] 

add(nums1, nums2) = 123 + 234 = 357

二.常规解法

常规解法为正常四则运算,主要分4步:

(1) 旋转数组,并获取较长和较短的数组 

(2) 计算公共部分的求和,如果 sum = value1 + value2 + add > 10 (字符串长度是否 > 1) ,则进位 add = 1,此处用变量 add 记录进位的大小,不进位时 add = 0

(3) 计算多出来的一部分,因为这一部分和短的没有公共部分,所以计算 value + add 是否大于10 并更新 add 即可

(4) 将 result 翻转得到最终结果

def add_num(_num1, _num2):
    _l1 = len(_num1)
    _l2 = len(_num2)
    # 翻转数组从最小位置开始相加
    _num1.reverse()
    _num2.reverse()
    # 根据长度判断大的数字和小的数字
    if _l1 >= _l2:
        long, short = _num1, _num2
    else:
        long, short = _num2, _num1
    # re 存储结果 add 存储进位
    re = []
    add = 0
    # 计算公共部分和
    for i in range(min(_l1, _l2)):
        value1 = _num1[i]
        value2 = _num2[i]
        add_re = str(value1 + value2 + add)
        # 计算进位
        if len(add_re) > 1:
            add = 1
        else:
            add = 0
        # 增加结果
        re.append(add_re[-1:])
    # 计算较长部分的和
    for j in range(min(_l1, _l2), max(_l1, _l2)):
        value = long[j]
        add_re = str(value + add)
        # 计算进位
        if len(add_re) > 1:
            add = 1
        else:
            add = 0
        # 增加结果
        re.append(add_re[-1:])
    re.reverse()
    return ''.join(re)
num1 = [1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 7, 8]
num2 = [2, 3, 4, 5, 6, 7, 6, 7, 8, 8, 9, 9, 9, 9, 9, 9]
result = add_num(num1, num2)
print(result)

三.链表解法

链表的解法与上面思路相似,只不过长短数组分段处理变成了两个链表同时处理,逐个遍历时只需要关系另一个链表的 node 是否有值,都有值时代表计算两者公共部分,只有一个链表 node 有值时则计算较长的部分。 node.val 记录当前值, node.next.val 记录下一个值,如果 l1.val + l2.val 大于10则进位,进位无需使用 add 变量记录,而是直接加给对应的 next_val ,依次类推。

1.辅助函数

ListNode 为链表对应的数据结构, initList 将列表转换为 ListNode,convert_list 将链表转换为列表并最终转换为计算结果

# 构造链表
class ListNode:
    def __init__(self, _val=0, _next=None):
        self.val = _val
        self.next = _next


# 初始化链表
def initList(data):
    head = ListNode(data[0])
    r = head
    p = head
    for i in data[1:]:
        node = ListNode(i)
        p.next = node
        p = p.next
    return r


#  链表转化为数组
def convert_list(head):
    ret = []
    if head is None:
        return
    node = head
    while node is not None:
        ret.append(node.val)
        node = node.next
    ret.reverse()
    return ''.join(list(map(lambda x: str(x), ret)))

2.求和主函数

判断 node 是否为 None,当前位置如果和 > 10,保留 value-10 的个位,然后进1位(next.val + 1)

def addTwoNumbers(_l1: ListNode, _l2: ListNode) -> ListNode:
    lrr = _l1
    while True:
        _l1.val = _l1.val + _l2.val
        if _l1.next is None and _l2.next is None and _l1.val < 10:
            break
        if _l1.next is None:
            _l1.next = ListNode(0)
        if _l2.next is None:
            _l2.next = ListNode(0)
        # 进位
        if _l1.val >= 10:
            _l1.val = _l1.val - 10
            _l1.next.val += 1
        _l1 = _l1.next
        _l2 = _l2.next
    return lrr
num1 = [1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 7, 8]
num2 = [2, 3, 4, 5, 6, 7, 6, 7, 8, 8, 9, 9, 9, 9, 9, 9]
l1 = initList(num1)
l2 = initList(num2)
print(convert_list(addTwoNumbers(l1, l2)))

3.时间比较

num1 = [1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 7, 8]
num2 = [2, 3, 4, 5, 6, 7, 6, 7, 8, 8, 9, 9, 9, 9, 9, 9]
st = time.time()
result = add_num(num1, num2)
print(result)
end1 = time.time()
l1 = initList(num1)
l2 = initList(num2)
print(convert_list(addTwoNumbers(l1, l2)))
end2 = time.time()
print(123452345678 + 2345676788999999)
end3 = time.time()
print((end1 - st), (end2 - end1), (end3 - end2))

基础解法和链表解法时间消耗相近,整体慢自带加法一个数量级。

2345800241345677
2345800241345677
2345800241345677
1.7881393432617188e-05 1.8835067749023438e-05 1.1920928955078125e-06


 


http://www.niftyadmin.cn/n/1235866.html

相关文章

20221211为论文添砖加瓦(1)

文章&#xff1a; A survey on machine learning methods for churn prediction Louis Geiler, Sverine Affeldt, Mohamed Nadif. A survey on machine learning methods for churn prediction. International Journal of Data Science and Analytics, Springer Verlag, 2022…

Python - 两数相除 递进版

一.引言 给定两个整数&#xff0c;被除数 dividend 和除数 divisor。将两数相除&#xff0c;要求不使用乘法、除法和 mod 运算符。返回被除数 dividend 除以除数 divisor 得到的商。整数除法的结果应当截去&#xff08;truncate&#xff09;其小数部分&#xff0c;例如&#x…

Python - 最大堆实现与应用

一.引言 前面提到了 PriorityQueue 踩坑&#xff0c;优先队列排序底层原理就是基于 Max Heap&#xff0c;下面捋一捋最大堆的基本实现与用法。首先明确最大堆及其实现的相关概念&#xff1a; A. 最大堆&#xff0c;又称大根堆&#xff08;大顶堆&#xff09;是指根节点&#…

STM32全局变量占用程序存储空间吗?

全局变量是否占用最终程序的存储空间&#xff0c;这个问题其实早在我们学习C语言的时候就已经告诉我们答案了。我隐约记得初学C语言的时候&#xff0c;书本上告诉我们&#xff1a; 全局自动变量——保存在读写数据段 全局静态变量——保存在读写数据段 全局常量——保存在只读数…

Spark - 大规模数据去重

一.引言 场景 : 商品 product 每日总销售记录量级 亿 级别起&#xff0c;去重 product 量大概 万 级别。每个商品有一个 state 标识其状态&#xff0c;该状态共3个值&#xff0c;分别为 "A", "B","C"。 统计&#xff1a; (1) 三个 state 下 p…

IAR C语言嵌入汇编问题

多条语句的格式如下&#xff1a;void QuickCopy(INT32U *addr, INT32U len, INT32U data){__asm("STMFD SP!, { R4 - R11 }\n""ADD R1,R0,R1\n""MOVR4, R2\n""MOVR5, R2\n""MOVR6, R2\n""MOVR7, R2\n""MOVR8…

Hive - Load Data 数据过长或过短

一.引言 Hive 可以通过 load data inpath 加载本地或者 hdfs 的数据到 hive 表中&#xff0c;有时会出现生成数据长于 hive 表字段或者短于 hive 表字段的情况&#xff0c;经过测试&#xff0c;两种情况下 Load Data 到 hive 表中均没有问题。 首先建立测试的 Hive 表&#x…

Python - 最小堆实现与应用

一.引言 前面写到了 最大堆的实现应用&#xff0c;趁热打铁把最小堆的也搞定&#xff0c;最小堆一定意思上和最大堆的实现相同&#xff0c;这不过“大”的概念变成了“小”&#xff0c;不同认知下&#xff0c;可以理解为两个是同一个事情&#xff0c;最小堆常用于大规模数据下…