当前位置: 首页 > news >正文

Python算法题集_两两交换链表中的节点

 Python算法题集_两两交换链表中的节点

  • 题24:两两交换链表中的节点
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【四节点法】
    • 2) 改进版一【列表操作】
    • 3) 改进版二【三指针法】
    • 4) 改进版三【递归大法】
  • 4. 最优算法

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

题24:两两交换链表中的节点

1. 示例说明

  • 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

    示例 1:

    img

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

    示例 2:

    输入:head = []
    输出:[]
    

    示例 3:

    输入:head = [1]
    输出:[1]
    

    提示:

    • 链表中节点的数目在范围 [0, 100]
    • 0 <= Node.val <= 100

2. 题目解析

- 题意分解

  1. 本题为两两交换链表中间的节点
  2. 本题的主要计算是2块,1是链表遍历,2是节点链接调整
  3. 基本的解法是单层循环,链表1读一遍,过程中执行节点链接调整,所以基本的时间算法复杂度为O(m)

- 优化思路

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

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

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

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

    1. 标准方法是一次循环,4个节点中,第2个节点链接第1个,第1个节点连接第3个或者第4个【如果第4个存在】

    2. 可以用列表结构进行节点调整,列表结构简单,方便维护

    3. 可以用三指针方式一次循环完成

    4. 此问题可以用嵌套思路,使用递归法


- 测量工具

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

3. 代码展开

1) 标准求解【四节点法】

一次遍历检查4个节点,完成节点链接调整

出类拔萃,超过85%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:@staticmethoddef swapPairs_base(head):if not head:return headif not head.next:return headtmpNode1, tmpNode2 = head, head.nexthead = tmpNode2while tmpNode1 and tmpNode2:tmpNode11 = tmpNode2.nexttmpNode12 = NonetmpNode1.next = tmpNode2.nexttmpNode2.next = tmpNode1if tmpNode11:tmpNode12 = tmpNode11.nextif tmpNode12:tmpNode1.next = tmpNode12tmpNode1 = tmpNode11tmpNode2 = tmpNode12return headresult = cfp.getTimeMemoryStr(Solution.swapPairs_base, ahead)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 运行结果
函数 swapPairs_base 的运行时间为 18.01 ms;内存使用量为 4.00 KB 执行结果 = 1

2) 改进版一【列表操作】

将链表转换为数组,再完成节点链接调整

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

import CheckFuncPerf as cfpclass Solution:@staticmethoddef swapPairs_ext1(head):if not head:return headif not head.next:return headlist_node = []while head:list_node.append(head)head = head.nextiLen = len(list_node)for iIdx in range(len(list_node) // 2):if iIdx * 2 + 2 > iLen:continuelist_node[iIdx*2+1].next = list_node[iIdx*2]if iIdx * 2 + 3 > iLen:list_node[iIdx * 2].next = Noneelif iIdx * 2 + 4 > iLen:list_node[iIdx * 2].next = list_node[iIdx * 2 + 2]else:list_node[iIdx * 2].next = list_node[iIdx * 2 + 3]return list_node[1]result = cfp.getTimeMemoryStr(Solution.swapPairs_ext1, ahead)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 运行结果
函数 swapPairs_ext1 的运行时间为 109.04 ms;内存使用量为 76.00 KB 执行结果 = 1

3) 改进版二【三指针法】

使用三指针结构遍历链表,完成节点链接调整

出类拔萃,超过85%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:@staticmethoddef swapPairs_ext2(head):dummyhead = ListNode(0)dummyhead.next = headnodepre = dummyheadnodeslow = dummyhead.nextif not nodeslow:return dummyhead.nextnodefast = nodeslow.nextwhile nodefast:nodeslow.next = nodefast.nextnodefast.next = nodeslownodepre.next = nodefastnodepre = nodeslownodeslow = nodeslow.nextif not nodeslow:breaknodefast = nodeslow.nextreturn dummyhead.nextresult = cfp.getTimeMemoryStr(Solution.swapPairs_ext2, ahead)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 运行结果
函数 swapPairs_ext2 的运行时间为 17.00 ms;内存使用量为 0.00 KB 执行结果 = 1

4) 改进版三【递归大法】

采用递归方式遍历链表,完成节点链接调整

出神入化,超过96%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:@staticmethoddef swapPairs_ext3(head):def swapnodepair(head):nodeleft = headif not nodeleft:return headnoderight = nodeleft.nextif not noderight:return headnodeleft.next = swapnodepair(noderight.next)noderight.next = nodeleftreturn noderightreturn swapnodepair(head)result = cfp.getTimeMemoryStr(Solution.swapPairs_ext3, ahead)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 运行结果
Traceback (most recent call last):......
[Previous line repeated 991 more times]
RecursionError: maximum recursion depth exceeded

4. 最优算法

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

nums = [ x for x in range(200000)]
def generateOneLinkedList(data):head = ListNode()current_node = headfor num in data:new_node = ListNode(num)current_node.next = new_nodecurrent_node = new_nodereturn head.next
ahead = generateOneLinkedList(nums)
result = cfp.getTimeMemoryStr(Solution.swapPairs_base, ahead)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))# 算法本地速度实测比较
函数 swapPairs_base 的运行时间为 18.01 ms;内存使用量为 4.00 KB 执行结果 = 1
函数 swapPairs_ext1 的运行时间为 109.04 ms;内存使用量为 76.00 KB 执行结果 = 1
函数 swapPairs_ext2 的运行时间为 17.00 ms;内存使用量为 0.00 KB 执行结果 = 1
Traceback (most recent call last):    # 递归法swapPairs_ext3超时......[Previous line repeated 991 more times]
RecursionError: maximum recursion depth exceeded

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

may the odds be ever in your favor ~

相关文章:

Python算法题集_两两交换链表中的节点

Python算法题集_两两交换链表中的节点 题24&#xff1a;两两交换链表中的节点1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【四节点法】2) 改进版一【列表操作】3) 改进版二【三指针法】4) 改进版三【递归大法】 4. 最优算法 本文为Python算法…...

米贸搜|Facebook在购物季使用的Meta广告投放流程

一、账户简化 当广告系列开始投放后&#xff0c;每个广告组都会经历一个初始的“机器学习阶段”。简化账户架构可以帮助AI系统更快获得广告主所需的成效。例如&#xff1a; 每周转化次数超过50次的广告组&#xff0c;其单次购物费用要低28%&#xff1b;成功结束机器学习阶段的…...

前端滚动组件分享

分享一个前端可视化常用的卡片列表滚动组件&#xff0c;常用于可视化项目左右两侧的卡片列表的滚动。效果如下图所示&#xff1a; 组件描述 当鼠标移入滚动区域时&#xff0c;滚动行为停止当鼠标再次离开时&#xff0c;滚动继续 源码展示 <template><div ref"…...

【linux开发工具】vim详解

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 “学如逆水行舟&#xff0…...

Compose | UI组件(十四) | Navigation-Data - 页面导航传递数据

文章目录 前言传参流程实例说明普通方式传值定义接受参数格式定义接受参数类型获取参数传入参数传参和接受参数效果图 结合 ViewModel 传递参数定义ViewModel在 navigation 定义 ViewModel 实例&#xff0c;并且传入 LoginScreen传入输入框中的值&#xff0c;并且跳转传值获取值…...

部署一个在线OCR工具

效果 安装 1.拉取镜像 # 从 dockerhub pull docker pull mmmz/trwebocr:latest 2.运行容器 # 运行镜像 docker run -itd --rm -p 10058:8089 --name trwebocr mmmz/trwebocr:latest 使用 打开浏览器输入 http://192.168.168.110:10058/ 愉快滴使用吧...

【北邮鲁鹏老师计算机视觉课程笔记】01 introduction

1 生活中的计算机视觉 生活中的各种计算机视觉识别系统已经广泛地应用起来了。 2 计算机视觉与其他学科的关系 认知科学和神经科学是研究人类视觉系统的&#xff0c;如果能把人类视觉系统学习得更好&#xff0c;可以迁移到计算机视觉。是计算机视觉的理论基础。 算法、系统、框…...

maven依赖报错处理(或者maven怎么刷新都下载不了依赖)

maven依赖报错&#xff0c;或者不报错&#xff0c;但是怎么刷新maven都没反应&#xff0c;可以试一下以下操作 当下载jar的时候&#xff0c;如果断网&#xff0c;或者连接超时的时候&#xff0c;会自动在文件夹中创建一个名为*lastupdate的文件&#xff0c;当有了这个文件之后…...

[VulnHub靶机渗透] dpwwn: 1

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…...

Android14音频进阶:MediaPlayerService如何启动AudioTrack 下篇(五十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…...

Python基础篇_修饰符(Decorators)【下】

上一篇&#xff1a;Python基础篇_修饰符&#xff08;Decorators&#xff09;【中】property、<attribute_name>.setter、<attribute_name>.deleter、functools.lru_cache(maxsizeNone) Python基础篇_修饰符&#xff08;Decorators&#xff09;【下】 Python基础篇_…...

C#,十进制展开数(Decimal Expansion Number)的算法与源代码

1 十进制展开数 十进制展开数&#xff08;Decimal Expansion Number&#xff09;的计算公式&#xff1a; DEN n^3 - n - 1 The decimal expansion of a number is its representation in base -10 (i.e., in the decimal system). In this system, each "decimal place…...

Vue3快速上手(一)使用vite创建项目

一、准备 在此之前&#xff0c;你的电脑&#xff0c;需要安装node.js,我这边v18.19.0 wangdymb 2024code % node -v v18.19.0二、创建 执行npm create vuelatest命令即可使用vite创建vue3项目 有的同学可能卡主不动&#xff0c;可能是npm的registry设置的问题 先看下&#x…...

使用navicat导出mysql离线数据后,再导入doris的方案

一、背景 doris本身是支持直接从mysql中同步数据的&#xff0c;但有时候&#xff0c;客户不允许我们使用doris直连mysql&#xff0c;此时就需要客户配合将mysql中的数据手工导出成离线文件&#xff0c;我们再导入到doris中 二、环境 doris 1.2 三、方案 doris支持多种导入…...

re:从0开始的CSS学习之路 1. CSS语法规则

0. 写在前面 现在大模型卷的飞起&#xff0c;感觉做页面的活可能以后就不需要人来做了&#xff0c;不知道现在还有没有学前端的必要。。。 1. HTML和CSS结合的三种方式 在HTML中&#xff0c;我们强调HTML并不关心显示样式&#xff0c;样式是CSS的工作&#xff0c;现在就轮到C…...

npm install express -g报错或一直卡着,亲测可解决

问题描述&#xff1a; 最近学习vue3前端框架&#xff0c;安装Node.js之后&#xff0c;在测试是否可行时&#xff0c;cmd窗口执行了&#xff1a;npm install express -g&#xff0c;发现如下图所示一直卡着不动&#xff0c;最后还报错了&#xff0c;网上找了好久&#xff0c;各…...

机器学习11-前馈神经网络识别手写数字1.0

在这个示例中&#xff0c;使用的神经网络是一个简单的全连接前馈神经网络&#xff0c;也称为多层感知器&#xff08;Multilayer Perceptron&#xff0c;MLP&#xff09;。这个神经网络由几个关键组件构成&#xff1a; 1. 输入层 输入层接收输入数据&#xff0c;这里是一个 28x…...

vscode wsl远程连接 权限问题

问题描述&#xff1a;执行命令时遇到Operation not permitted 和 Permission denied问题&#xff0c;是有关ip地址和创建文件的权限问题&#xff0c;参考网络上更改wsl.conf文件等方法均无法解决&#xff0c;只能加sudo来解决...

VED-eBPF:一款基于eBPF的内核利用和Rootkit检测工具

关于VED-eBPF VED-eBPF是一款功能强大的内核漏洞利用和Rootkit检测工具&#xff0c;该工具基于eBPF技术实现其功能&#xff0c;可以实现Linux操作系统运行时内核安全监控和漏洞利用检测。 eBPF是一个内核内虚拟机&#xff0c;它允许我们直接在内核中执行代码&#xff0c;而无…...

配置ARM交叉编译工具的通用步骤

ARM交叉编译工具是用于编译在ARM架构上运行的代码的工具。这些工具允许开发者在一种架构&#xff08;通常是x86或x64&#xff09;上编写和编译代码&#xff0c;然后将其移植到ARM架构上运行。 ARM交叉编译工具链通常包括编译器、链接器、调试器和其他必要的工具&#xff0c;用…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

Element-Plus:popconfirm与tooltip一起使用不生效?

你们好&#xff0c;我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip&#xff0c;产品要求是两个需要结合一起使用&#xff0c;也就是鼠标悬浮上去有提示文字&#xff0c;并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...

深入理解 C++ 左值右值、std::move 与函数重载中的参数传递

在 C 编程中&#xff0c;左值和右值的概念以及std::move的使用&#xff0c;常常让开发者感到困惑。特别是在函数重载场景下&#xff0c;如何合理利用这些特性来优化代码性能、确保语义正确&#xff0c;更是一个值得深入探讨的话题。 在开始之前&#xff0c;先提出几个问题&…...