Python算法题集_相交链表

 Python算法题集_相交链表

  • 题41:相交链表
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【双层循环】
    • 2) 改进版一【双指针】
    • 3) 改进版二【哈希检索-集合】
    • 4) 改进版三【哈希检索-字典】
  • 4. 最优算法

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

题41:相交链表

1. 示例说明

  • 给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

    图示两个链表在节点 c1 开始相交**:**

    img

    题目数据 保证 整个链式结构中不存在环。

    注意,函数返回结果后,链表必须 保持其原始结构

    自定义评测:

    评测系统 的输入如下(你设计的程序 不适用 此输入):

    • intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
    • listA - 第一个链表
    • listB - 第二个链表
    • skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
    • skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数

    评测系统将根据这些输入创建链式数据结构,并将两个头节点 headAheadB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案

    示例 1:

    img

    输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
    输出:Intersected at '8'
    解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
    从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
    在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
    — 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。
    

    示例 2:

    img

    输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
    输出:Intersected at '2'
    解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
    从各自的表头开始算起,链表 A 为 [1,9,1,2,4],链表 B 为 [3,2,4]。
    在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
    

    示例 3:

    img

    输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
    输出:null
    解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
    由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
    这两个链表不相交,因此返回 null 。
    

    提示:

    • listA 中节点数目为 m
    • listB 中节点数目为 n
    • 1 <= m, n <= 3 * 104
    • 1 <= Node.val <= 105
    • 0 <= skipA <= m
    • 0 <= skipB <= n
    • 如果 listAlistB 没有交点,intersectVal0
    • 如果 listAlistB 有交点,intersectVal == listA[skipA] == listB[skipB]

    **进阶:**你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方案?


2. 题目解析

- 题意分解

  1. 本题为两个单向链表的指针是否指向同一值的检测
  2. 本题的主要计算有2处,1是链表遍历,2是对象比较
  3. 基本的解法是双层循环,链表A遍历第一层,链表B遍历第二层,所以基本的时间算法复杂度为O(mn)

- 优化思路

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

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

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

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

    1. 可以用哈希值方法检索相同对象,哈希检索包括集合、字典

    2. 可以用双指针法将链表挂接记性检测


- 测量工具

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

3. 代码展开

1) 标准求解【双层循环】

双层循环,果然超时在这里插入图片描述

import CheckFuncPerf as cfp

def getIntersectionNode_base(headA: ListNode, headB: ListNode):
 val_a, val_b = headA, headB
 while val_a:
     while val_b:
         if val_a == val_b:
             return  val_a
         val_b=val_b.next
         if not val_b:
             val_b=headB
             break
     val_a=val_a.next
     if not val_a:
         return None
     
result = cfp.getTimeMemoryStr(getIntersectionNode_base, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 getIntersectionNode_base 的运行时间为 10133.78 ms;内存使用量为 4.00 KB 执行结果 = 50001

2) 改进版一【双指针】

双指针法 马马虎虎,超过63%在这里插入图片描述

import CheckFuncPerf as cfp

def getIntersectionNode_ext1(headA: ListNode, headB: ListNode):
 val_a, val_b = headA, headB
 while val_a != val_b:
     val_a = val_a.next if val_a else headB
     val_b = val_b.next if val_b else headA
 return val_a

result = cfp.getTimeMemoryStr(getIntersectionNode_ext1, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 getIntersectionNode_ext1 的运行时间为 1.00 ms;内存使用量为 0.00 KB 执行结果 = 50001

3) 改进版二【哈希检索-集合】

使用set集合进行哈希检索 有所改进,超过76%在这里插入图片描述

import CheckFuncPerf as cfp

def getIntersectionNode_ext2(headA: ListNode, headB: ListNode):
 set_visited = set()
 while headA is not None:
     set_visited.add(headA)
     headA = headA.next
 while headB is not None:
     if headB in set_visited:
         return headB
     headB = headB.next
 return None

result = cfp.getTimeMemoryStr(getIntersectionNode_ext2, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 getIntersectionNode_ext2 的运行时间为 2.00 ms;内存使用量为 76.00 KB 执行结果 = 50001

4) 改进版三【哈希检索-字典】

使用dict字典进行哈希检索 指标优良,超越90%在这里插入图片描述

import CheckFuncPerf as cfp

def getIntersectionNode_ext3(headA: ListNode, headB: ListNode):
 dict_visited = {}
 while headA is not None:
     dict_visited[headA] = dict_visited.get(headA, 0)
     dict_visited[headA] += 1
     headA = headA.next
 while headB is not None:
     if headB in dict_visited:
         return headB
     headB = headB.next
 return None

result = cfp.getTimeMemoryStr(getIntersectionNode_ext3, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 getIntersectionNode_ext3 的运行时间为 5.00 ms;内存使用量为 0.00 KB 执行结果 = 50001

4. 最优算法

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

# 超时测试
nums1 = [ x for x in range(10001, 20000)]
nums2 = [ x for x in range(30001, 40000)]
nums3 = [ x for x in range(50001, 60000)]
def generateOneLinkedList(data):
    head = ListNode(-100)
    current_node = head
    for num in data:
        new_node = ListNode(num)
        current_node.next = new_node
        current_node = new_node
    return head.next, new_node
head1, tail1 = generateOneLinkedList(nums1)
head2, tail2 = generateOneLinkedList(nums2)
head3, tail3 = generateOneLinkedList(nums3)
tail1.next = head3
tail2.next = head3

result = cfp.getTimeMemoryStr(getIntersectionNode_base, head1, head2)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 算法本地速度实测比较
函数 getIntersectionNode_base 的运行时间为 10133.78 ms;内存使用量为 4.00 KB 执行结果 = 50001
函数 getIntersectionNode_ext1 的运行时间为 1.00 ms;内存使用量为 0.00 KB 执行结果 = 50001
函数 getIntersectionNode_ext2 的运行时间为 2.00 ms;内存使用量为 76.00 KB 执行结果 = 50001
函数 getIntersectionNode_ext3 的运行时间为 5.00 ms;内存使用量为 0.00 KB 执行结果 = 50001

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

may the odds be ever in your favor ~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

游戏服务器购买多少钱1个月?买一年贵吗?

游戏服务器购买多少钱1个月&#xff1f;阿里云26元1个月、腾讯云32元1个月。买一年贵吗&#xff1f;不贵。 游戏服务器租用多少钱一年&#xff1f;1个月游戏服务器费用多少&#xff1f;阿里云游戏服务器26元1个月、腾讯云游戏服务器32元&#xff0c;游戏服务器配置从4核16G、4…

OSI七层模型

文章目录 定义各层功能定义在 OSI 模型中如何进行通信OSI 模型有哪些替代方案&#xff1a;TCP/IP 定义 OSI是一种开放系统互连参考模型 (Open System Interconnect 简称OSI&#xff09;&#xff0c;是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互…

[职场] 集成电路IC设计工程师求职简历工作经历范文(精选4篇) #职场发展#其他

集成电路IC设计工程师求职简历工作经历范文&#xff08;精选4篇&#xff09; 集成电路IC设计工程师在找工作做简历的时候&#xff0c;经常不知道求职简历中的工作经历板块怎么写&#xff0c;下面是简历网小编整理的适合集成电路IC设计工程师在做简历时写的工作经历范文4篇&…

40000000人民币有多重

在日常生活中&#xff0c;我们经常看到大量现金的重量作为一个有趣的话题。那么&#xff0c;40000000人民币到底有多重呢&#xff1f;本文将详细介绍如何计算这个问题&#xff0c;并讨论与现金重量相关的因素。 首先&#xff0c;我们需要了解人民币纸币的重量。一张崭新的100元…

MySQL篇----第十篇

系列文章目录 文章目录 系列文章目录前言一、MyISAM Static 和 MyISAM Dynamic 有什么区别?二、如果一个表有一列定义为 TIMESTAMP,将发生什么?三、你怎么看到为表格定义的所有索引?四、LIKE 声明中的%和_是什么意思?五、列对比运算符是什么?前言 前些天发现了一个巨牛…

【力扣】整数反转,判断是否溢出的数学解法

整数反转原题地址 方法一&#xff1a;数学 反转整数 如何反转一个整数呢&#xff1f;考虑整数操作的3个技巧&#xff1a; xmod10可以取出x的最低位&#xff0c;如x123&#xff0c;xmod103。x/10可以去掉x的最低位&#xff0c;如x123&#xff0c;x/10&#xff0c;x12。xx*10…

26 使用 Samba 实现文件共享

Samba 文件共享服务 Samba 服务程序现在已经成为在 Linux 系统与Windows 系统之间共享文件的最佳选择 详细配置请转Samba服务 安装 [rootlocalhost ~]# yum install samba -ySamba 服务程序的主配置文件&#xff0c;只有 37 行。 第 5&#xff5e;8 行参数中所提到的 cups…

仰暮计划|“用心感悟使我获取了艺术真谛,自律如始让我获得了人生成功,我将继续在艺术道路上走下去”

口述人:郭敬东&#xff08;男&#xff09; 整理人:马静 口述人与整理人关系:姥爷与外孙女 口述人基本信息:现60岁&#xff0c;1963年出生于湖北省大悟县刘集镇金鼓村&#xff0c;1987年移居到河南省焦作市&#xff0c;现居河南省焦作市高新区。 引言:在得知要讲述自己的经历…

企业数字化转型面临什么挑战?

数字化转型是一个复杂且持续的过程&#xff0c;涉及将数字技术集成到组织的各个方面&#xff0c;从根本上改变组织的运营方式和为客户提供价值的方式。虽然具体的挑战可能因企业的性质和规模而异&#xff0c;但一些常见的挑战包括&#xff1a; 1.抵制变革&#xff1a; 文化阻…

STM32单片机的基本原理与应用(七)

超声波测距实验 基本原理 超声波测距实验是STM32单片机通过控制HC-SR04超声波模块&#xff0c;使其发送超声波&#xff0c;遇到物体反射回超声波来实现距离测量&#xff0c;其原理就是在发射超声波到接收超声波会有一段时间&#xff0c;而超声波在空气中传播的速度为声速&…

python打包exe,并发布windows服务实践

操作实践 1、编写python程序&#xff0c;按照自己的需求编写 以下是案例 # -*- coding:utf-8 -*- import win32serviceutil import win32service import win32event import win32timezone #不加导入&#xff0c;打包后运行会报错&#xff0c;原因未知&#xff0c;暂时不…

小白Linux学习笔记-Linux内核

Linux内核 文章目录 Linux内核WHEREWHATmoudules.dep 文件depmod 命令depmod 实验lsmod 命令modinfo 命令内核模块的观察实验 内核模块的加载与移除:insmod, modprobe, rmmodinsmod 命令modprobe 命令rmmod 命令内核模块的加载与移除实验 内核模块的额外参数设定:/etc/modprobe…

二道经典OJ题带你入门回溯剪枝算法

风起于青萍之末 浪成于微澜之间 &#x1f3a5;个人主页 &#x1f525;个人专栏 &#x1f3a5;前期回顾-环形链表 目录 回溯算法的简介 N皇后问题 思路 代码测试 N皇后 思路 判断一竖列是否有皇后 判断对角线是否有皇后 代码测试 回溯算法的简介 回溯是递归的副产品&#xff0…

计算机设计大赛 深度学习+python+opencv实现动物识别 - 图像识别

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 inception_v3网络5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; *…

5-2、S曲线计算【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍S曲线的基本变换&#xff0c;将基本形式的S曲线变换成为任意过两点的S曲线&#xff0c;为后续步进电机S曲线运动提供理论支撑 一.计算目标 ①计算经过任意不同两点的S曲线方程 ②可调节曲线平…

Zephyr NRF7002 实现AppleJuice

BLE的基础知识 ble的信道和BR/EDR的信道是完全不一样的。但是范围是相同的&#xff0c;差不多也都是2.4Ghz的频道。可以简单理解为空中有40个信道0~39信道。两个设备在相同的信道里面可以进行相互通信。 而这些信道SIG又重新编号&#xff1a; 这个编号就是把37 38 39。 3个信道…

「HarmonyOS」CustomDialogController自定义弹窗使用方法

需求背景&#xff1a; 在开发的过程中&#xff0c;总会遇到一些功能需要使用到弹窗进行信息的输入和修改&#xff0c;如用户个人信息的修改&#xff1b;在UI设计上每个App通常都会有各自的样式&#xff0c;而不是使用系统的标准样式&#xff0c;所以通常我们需要进行自定义弹窗…

C++学习Day04之常函数和常对象

目录 一、程序及输出1.1 常函数1.1.1 不能修改对象的成员变量1.1.2 常函数可以被常对象和非常对象调用 1.2 常对象1.2.1 对象的成员变量不能被修改1.2.2 只能调用常函数&#xff0c;不能调用非常函数1.2.3 const_cast 调用非常函数 1.3 常函数中或常对象修改成员变量 二、分析与…

DevOps落地笔记-17|度量指标:寻找真正的好指标?

前面几个课时端到端地介绍了软件开发全生命周期中涉及的最佳实践&#xff0c;经过上面几个步骤&#xff0c;企业在进行 DevOps 转型时技术方面的问题解决了&#xff0c;这个时候我们还缺些什么呢&#xff1f;事实上很多团队和组织在实施 DevOps 时都专注于技术&#xff0c;而忽…

zxxxxczzvdsgbhfdb

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 磁盘满的本质分析 专栏&#xff1a;《Linux从小白到大神》 | 系统学习Linux开发、VIM/GCC/GDB/Make工具…