Python算法题集_两数相加

 Python算法题集_两数相加

  • 题2:两数相加
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【直接相加】
    • 2) 改进版一【对齐链表】
    • 3) 改进版二【数组求和】
  • 4. 最优算法

本文为Python算法题集之一的代码示例

题2:两数相加

1. 示例说明

  • 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

    请你将两个数相加,并以相同形式返回一个表示和的链表。

    你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

    示例 1:

    img

    输入:l1 = [2,4,3], l2 = [5,6,4]
    输出:[7,0,8]
    解释:342 + 465 = 807.
    

    示例 2:

    输入:l1 = [0], l2 = [0]
    输出:[0]
    

    示例 3:

    输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
    输出:[8,9,9,9,0,0,0,1]
    

    提示:

    • 每个链表中的节点数在范围 [1, 100]
    • 0 <= Node.val <= 9
    • 题目数据保证列表表示的数字不含前导零

2. 题目解析

- 题意分解

  1. 本题为两个链表结构的数字求和
  2. 本题的主要计算有2处,1是链表遍历,2是数字求和
  3. 基本的解法是循环,链表1读一遍,链表2读一遍,所以基本的时间算法复杂度为O(m+n)

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 链表1、链表2按顺序求和计算是标准的方式

    2. 如果对链表1、链表2的数据进行位置对齐,代码维护性会更好,性能也可能可以提升

    3. 可以用列表结构进行合并再转换为链表,看看效果


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大,因此需要本地化测试解决这个问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题很难超时,本地化超时测试用例自己生成,详见【最优算法章节】

3. 代码展开

1) 标准求解【直接相加】

链表直接求和,性能表现不错

性能优异,超越92在这里插入图片描述

import CheckFuncPerf as cfpdef addTwoNumbers_base(l1, l2):result = ListNode()sumtmp = 0lastnode = ListNode()result.next = lastnodewhile 1:sumtmp = (l1.val + l2.val + sumtmp) // 10valtmp = (l1.val + l2.val + sumtmp) % 10now = ListNode(valtmp)sumtmp = sumtmplastnode.next = nowlastnode = lastnode.nextl1 = l1.next or ListNode(0)l2 = l2.next or ListNode(0)if (l1.next is Noneand l2.next is Noneand not sumtmpand l1.val == 0and l2.val == 0):breakreturn result.next.nextresult = cfp.getTimeMemoryStr(Solution.addTwoNumbers_base, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 addTwoNumbers_base 的运行时间为 158.03 ms;内存使用量为 16644.00 KB 执行结果 = <__main__.ListNode object at 0x000002115CF31860>

2) 改进版一【对齐链表】

将两个链表先对齐后,再进行求和

马马虎虎,超过69%在这里插入图片描述

import CheckFuncPerf as cfpdef addTwoNumbers_ext1(l1, l2):head = newnode = ListNode()len1, len2 = 0, 0l1_copy, l2_copy = l1, l2while l1.next: len1 += 1l1 = l1.nextwhile l2.next:len2 += 1l2 = l2.nextif len1 > len2: for iIdx in range(len1 - len2):l2.next = ListNode(0)l2 = l2.nextelif len2 > len1:for iIdx in range(len2 - len1):l1.next = ListNode(0)l1 = l1.nextsumtmp = 0while l1_copy: valtmp = l1_copy.val + l2_copy.val + sumtmpsumtmp = valtmp // 10valtmp = valtmp % 10newnode.next = ListNode(valtmp)newnode = newnode.nextl1_copy = l1_copy.nextl2_copy = l2_copy.nextif sumtmp == 1:newnode.next = ListNode(1)return head.nextresult = cfp.getTimeMemoryStr(Solution.addTwoNumbers_ext1, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 addTwoNumbers_ext1 的运行时间为 129.03 ms;内存使用量为 16640.00 KB 执行结果 = <__main__.ListNode object at 0x000002115DF766D8>

3) 改进版二【数组求和】

将链表转换为数组,再求和转为链表,性能下降比较厉害

马马虎虎,超过66%在这里插入图片描述

import CheckFuncPerf as cfpdef addTwoNumbers_ext2(l1, l2):if l1 is None:return l2elif l2 is None:return l1list1, list2 = [], []while l1:list1.insert(0, l1.val)l1 = l1.nextwhile l2:list2.insert(0, l2.val)l2 = l2.nextnum1, iunit = 0, 1for iIdx in range(len(list1)):num1 += list1[-iIdx-1] * iunitiunit *= 10num2, iunit = 0, 1for iIdx in range(len(list2)):num2 += list2[-iIdx-1] * iunitiunit *= 10num3 = num1 + num2list3 = str(num3)num3Node = ListNode(-100)headNode = num3Nodefor iIdx in range(len(list3)):num3Node.next = ListNode(int(list3[-iIdx-1]))num3Node = num3Node.nextreturn headNode.nextresult = cfp.getTimeMemoryStr(Solution.CheckFuncPerf, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 addTwoNumbers_ext2 的运行时间为 8411.89 ms;内存使用量为 17080.00 KB 执行结果 = <__main__.ListNode object at 0x000002115DF76358>

4. 最优算法

根据本地日志分析,最优算法为第2种addTwoNumbers_ext1

import random
nums1 = [random.randint(0, 9) for x in range(100000)]
nums2 = [random.randint(0, 9) for x in range(100000)]
def generateOneLinkedList(data):head = ListNode(-100)current_node = headfor num in data:new_node = ListNode(num)current_node.next = new_nodecurrent_node = new_nodereturn head.next, new_node
head1, tail1 = generateOneLinkedList(nums1)
head2, tail2 = generateOneLinkedList(nums2)
result = cfp.getTimeMemoryStr(Solution.addTwoNumbers_base, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 算法本地速度实测比较
函数 addTwoNumbers_base 的运行时间为 158.03 ms;内存使用量为 16644.00 KB 执行结果 = <__main__.ListNode object at 0x000002115CF31860>
函数 addTwoNumbers_ext1 的运行时间为 129.03 ms;内存使用量为 16640.00 KB 执行结果 = <__main__.ListNode object at 0x000002115DF766D8>
函数 addTwoNumbers_ext2 的运行时间为 8411.89 ms;内存使用量为 17080.00 KB 执行结果 = <__main__.ListNode object at 0x000002115DF76358>

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/460977.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Authorization Server Spring Security密码加密

文章目录 一、修改密码编码器二、效果三、注意点1. RegisteredClient2. UserDetailsService 一、修改密码编码器 以BCryptPasswordEncoder举例。 直接将其注册成PasswordEncoder 的Bean即可。 Beanpublic PasswordEncoder passwordEncoder() {// 密码为明文方式 // ret…

创建本地yum源并安装tree命令(openEuler-20.03-LTS-SP3)

步骤 1&#xff1a;下载ISO镜像 首先&#xff0c;您需要从提供的URL下载ISO镜像文件&#xff1a; cd /opt wget https://mirrors.dotsrc.org/openeuler/openEuler-20.03-LTS-SP3/ISO/x86_64/openEuler-20.03-LTS-SP3-x86_64-dvd.iso步骤 2&#xff1a;挂载ISO镜像 接下来&am…

DMA直接内存访问,STM32实现高速数据传输使用配置

1、DMA运用场景 随着智能化、信息化的不断推进&#xff0c;嵌入式设备的数据处理量也呈现指数级增加&#xff0c;因此对于巨大的数据量处理的情况时&#xff0c;必须采取其它的方式去替CPU减负&#xff0c;以保证嵌入式设备性能。例如SD卡存储器和音视频、网络高速通信等其它情…

Java后端技术助力,党员学习平台更稳定

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Web APIs 2 事件

Web APIs 2 事件 事件监听案例&#xff1a;广告关闭案例&#xff1a;随机问答 事件监听版本事件类型案例&#xff1a;轮播图完整焦点事件键盘事件输入事件案例&#xff1a;评论字数统计 事件对象获取事件对象事件对象常用属性案例&#xff1a;评论回车发布 环境对象this回调函数…

react将选中文本自动滑动到容器可视区域内

// 自动滚动到可视区域内useEffect(() > {const target ref;const wrapper wrapperRef?.current;if (target && wrapperRef) {const rect target.getBoundingClientRect();const wrapperRect wrapper.getBoundingClientRect();const isVisible rect.bottom &l…

跟着pink老师前端入门教程-day21+22

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

2024年【R2移动式压力容器充装】考试题及R2移动式压力容器充装复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 R2移动式压力容器充装考试题是安全生产模拟考试一点通总题库中生成的一套R2移动式压力容器充装复审考试&#xff0c;安全生产模拟考试一点通上R2移动式压力容器充装作业手机同步练习。2024年【R2移动式压力容器充装】…

Markdown:简洁高效的文本标记语言

引言 在当今信息爆炸的时代&#xff0c;我们需要一种简洁、高效的文本标记语言来排版和发布内容。Markdown应运而生&#xff0c;它是一种轻量级的文本标记语言&#xff0c;以其简单易学、易读易写的特点&#xff0c;成为了广大写作者的首选工具。本文将介绍Markdown的语法优缺…

适用于 Windows 和 Mac 的 16 款最佳数据恢复软件

数据恢复软件是找回因硬盘损坏、病毒攻击或意外删除数据等原因而在设备上丢失的数据的最佳方法。在数字世界中&#xff0c;丢失数据是一件非常糟糕的事情&#xff0c;这会让许多人的情况变得更糟。使用最佳数据恢复软件可以减轻您必须努力恢复丢失数据的压力。它将带回您的大部…

推荐研发度量思码逸的研发度量工具及视频教学

目前国内做研发度量中&#xff0c;思码逸的研发度量工具的确做的不错&#xff0c;网址是&#xff1a;思码逸-专业的软件研发效能度量分析平台 看到一个不错的介绍视频&#xff1a;《让数据说话&#xff0c;高效盘点企业研发效能》&#xff0c; 地址是&#xff1a;视频课程&…

注意啦,MySQL8.0最新版是没有utf8选项,但是有utf8mb3和utf8mb4选项

今天在安装完MySQL最新版&#xff08;8.0.36&#xff09;&#xff0c;然后用navicat连接数据&#xff0c;创建数据库的时候&#xff0c;发现: MySQL最新版是没有utf8选项&#xff0c;但是有utf8mb3和utf8mb4选项 然后就只能卸载掉最新版&#xff0c;安装了8.0.28. &#xff08…