Python算法题集_合并两个有序链表

 Python算法题集_合并两个有序链表

  • 题21:合并两个有序链表
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【直接合并】
    • 2) 改进版一【列表合并】
    • 3) 改进版二【递归大法】
  • 4. 最优算法

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

题21:合并两个有序链表

1. 示例说明

  • 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

    示例 1:

    img

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

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

示例 3:

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

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1l2 均按 非递减顺序 排列

2. 题目解析

- 题意分解

  1. 本题为两个单项链表带顺序合并
  2. 本题的主要计算有2处,1是链表遍历,2是元素比较
  3. 基本的解法是单层循环,链表1、链表2依次添加,所以基本的时间算法复杂度为O(m+n)

- 优化思路

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

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

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

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

    1. 由于链表已经排序,因此从左侧进行比较合并是常规做法

    2. 可以使用列表将链表节点排序后连接,性能下降,但是可维护性提升

    3. 可以搬出递归大法,但是超时测试就不行了,因为递归的层次有上限【之前的算法已经出现过,好像是990层】


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大,因此需要本地化测试解决这个问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 超时测试用例文件是官网的,已上传到CSDN,地址在这里:力扣算法题超时测试用例:缺失的第一个正数,数组长度10W
  • 本题很难超时,本地化超时测试用例自己生成,详见【最优算法章节】

3. 代码展开

1) 标准求解【直接合并】

列表节点依次比较合并,其实是性能最高的

依次合并,超过60%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:@staticmethoddef mergeTwoList_base(list1, list2):if not list1:return list2if not list2:return list1if list1.val <= list2.val:icurval = list1.valnodenew = list1list1 = list1.nextelse:icurval = list2.valnodenew = list2list2 = list2.nextnodestep = nodenewwhile list1 and list2:if list1.val <= list2.val:if list1.val == icurval:icurval = list1.valnodestep.next = list1list1 = list1.nextelse:if list2.val == icurval:icurval = list2.valnodestep.next = list2list2 = list2.nextnodestep = nodestep.nextif not list1:nodestep.next = list2if not list2:nodestep.next = list1return nodenewresult = cfp.getTimeMemoryStr(Solution.mergeTwoList_base, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 运行结果
函数 mergeTwoList_base 的运行时间为 80.02 ms;内存使用量为 4.00 KB 执行结果 = 1

2) 改进版一【列表合并】

采用列表排序和并,代码简洁易维护,不过性能下降
注意:即使原始链表未排序,此代码一样能合并称为排序链表

性能优良,超过80%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:@staticmethoddef mergeTwoList_ext1(list1, list2):if list1 is None:return list2elif list2 is None:return list1listNode = []while list1:listNode.append([list1.val, list1])list1 = list1.nextwhile list2:listNode.append([list2.val, list2])list2 = list2.nextsorted_note = sorted(listNode, key=lambda x: x[0])for iIdx in range(len(sorted_note)-1):sorted_note[iIdx][1].next = sorted_note[iIdx+1][1]return sorted_note[0][1]result = cfp.getTimeMemoryStr(Solution.mergeTwoList_ext1, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 运行结果
函数 mergeTwoList_ext1 的运行时间为 206.05 ms;内存使用量为 1228.00 KB 执行结果 = 1

3) 改进版二【递归大法】

采用递归大法进行排序,代码更简洁,但是递归有限制,反而不如列表更好维护

性能优良,超过80%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:@staticmethoddef mergeTwoList_ext2(list1, list2):if list1 is None:return list2elif list2 is None:return list1elif list1.val < list2.val:list1.next = Solution.mergeTwoList_ext2(list1.next, list2)return list1else:list2.next = Solution.mergeTwoList_ext2(list1, list2.next)return list2result = cfp.getTimeMemoryStr(Solution.mergeTwoList_ext2, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 运行结果
Traceback (most recent call last):......
RecursionError: maximum recursion depth exceeded in comparison

4. 最优算法

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

import random
nums1 = [random.randint(1, 1000000) for x in range(100000)]
nums2 = [random.randint(1, 1000000) for x in range(100000)]
nums1.sort()
nums2.sort()
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.mergeTwoList_base, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 6种算法本地速度实测比较
函数 mergeTwoList_base 的运行时间为 80.02 ms;内存使用量为 4.00 KB 执行结果 = 1
函数 mergeTwoList_ext1 的运行时间为 206.05 ms;内存使用量为 1228.00 KB 执行结果 = 1
Traceback (most recent call last): 【mergeTwoList_ext2报错】......
RecursionError: maximum recursion depth exceeded in comparison

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

may the odds be ever in your favor ~

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

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

相关文章

使用x86架构+Nvidia消费显卡12G显存,搭建智能终端,将大模型本地化部署,说不定是未来方向,开源交互机器人设计

1&#xff0c;大模型本地部署 视频说明地址&#xff1a; https://www.bilibili.com/video/BV1BF4m1u769/ 【创新思考】&#xff08;1&#xff09;&#xff1a;使用x86架构Nvidia消费显卡12G显存&#xff0c;搭建智能终端&#xff0c;将大模型本地化部署&#xff0c;语音交互机…

Stable Diffusion 模型下载:Disney Pixar Cartoon Type A(迪士尼皮克斯动画片A类)

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 目前还没有一个好的皮克斯迪士尼风格的卡通模型&#xff0c;所以我决定自己制作一个。这是将皮克斯风格模型与我自己的Loras合并在一起&#xff0c;创建一个通用的…

UE4运用C++和框架开发坦克大战教程笔记(十八)(第55~57集)

UE4运用C和框架开发坦克大战教程笔记&#xff08;十八&#xff09;&#xff08;第55~57集&#xff09; 55. UI 进入退出动画HideOther 面板出现时隐藏其他面板添加面板出现和收起的动画效果编写遮罩管理器前的准备 56. 弹窗进入界面57. UI 显示隐藏与遮罩转移完善遮罩管理器 55…

蓝桥杯刷题day07——斐波那契与7

1、题目描述 斐波那契数列的递推公式为:FnFn-1Fn-2, 其中F1F21. 请问, 斐波那契数列的第 1 至 202202011200 项&#xff08;含&#xff09;中, 有多少项的个位 是 7 。 答案提交 这是一道结果填空的题, 你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填…

157基于matlab的GVF-snake算法能自动收敛到目标区域

基于matlab的GVF-snake算法能自动收敛到目标区域。关键技术GVF snake模型算法matlab源程序&#xff0c;GVF是根据光流场原理,利用变分方法,从图像中得到的一种向量场,该向量场被称为梯度矢量流(GVF)场。 Snake模型称为动态轮廓模型&#xff08;Active Contour Model&#xff0…

图灵日记之java奇妙历险记--抽象类和接口

目录 抽象类概念抽象类语法 接口概念规则使用特性实现多个接口接口的继承接口使用实例Clonable接口和深拷贝抽象类和接口的区别 Object类 抽象类 概念 在面向对象的概念中,所有对象都是通过类来描述的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够…

linux、windows 安装 vue-cli

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统&#xff0c;提供&#xff1a; 通过 vue/cli 实现的交互式的项目脚手架。 通过 vue/cli vue/cli-service-global 实现的零配置原型开发。 一个运行时依赖 (vue/cli-service) 可升级&#xff1b; 基于 webpack 构建&#…

第九个知识点:内部对象

Date对象: <script>var date new Date();date.getFullYear();//年date.getMonth();//月date.getDate();//日date.getDay();//星期几date.getHours();//时date.getMinutes();//分date.getSeconds();//秒date.getTime();//获取时间戳&#xff0c;时间戳时全球统一&#x…

Django模板(二)

标签if 标签在渲染过程中提供使用逻辑的方法,比如:if和for 标签被 {% 和 %} 包围,如下所示: 由于在模板中,没有办法通过代码缩进判断代码块,所以控制标签都需要有结束的标签 if判断标签{% if %} {% endif %} : # athlete_list 不为空 {% if athlete_list %}# 输出 ath…

152基于matlab的GUI滚动轴承特征频率计算

基于matlab的GUI滚动轴承特征频率计算&#xff0c;输入轴承参数&#xff0c;包括转速&#xff0c;节圆直径、滚子直径、滚子数、接触角&#xff0c;就可得滚动特征频率结果&#xff0c;程序已调通&#xff0c;可直接运行。 152 matlab 轴承特征频率 GUI (xiaohongshu.com)

Leetcode刷题笔记题解(C++):64. 最小路径和

思路一&#xff1a;dfs深度优先搜索&#xff0c;然后取最小路径值&#xff0c;但是时间消耗较大&#xff0c;时间复杂度可能不满足&#xff0c;代码如下&#xff1a; class Solution { public:int res 1000000;int rows,cols;int minPathSum(vector<vector<int>>…

LINUX基础培训二十四之shell字符串处理

一、shell字符串 字符串&#xff08;String&#xff09;就是一系列字符的组合。字符串是 Shell 编程中最常用的数据类型之一&#xff08;除了数字和字符串&#xff0c;也没有其他类型了&#xff09;。字符串可以由单引号 包围&#xff0c;也可以由双引号" "包围&…