Python算法题集_删除链表的倒数第 N 个结点

news2025/1/19 2:33:33

 Python算法题集_删除链表的倒数第 N 个结点

  • 题19:删除链表的倒数第 N 个结点
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【二次遍历】
    • 2) 改进版一【快慢指针】
    • 3) 改进版二【列表裁剪】
  • 4. 最优算法

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

题19:删除链表的倒数第 N 个结点

1. 示例说明

    • 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

      示例 1:

      img

      输入:head = [1,2,3,4,5], n = 2
      输出:[1,2,3,5]
      
      **示例 2:**
    
    

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

    **示例 3:**
    
    

    输入:head = [1,2], n = 1
    输出:[1]

     
    
    **提示:**
    
    - 链表中结点的数目为 `sz`
    - `1 <= sz <= 30`
    - `0 <= Node.val <= 100`
    - `1 <= n <= sz`
    
     
    
    **进阶:**你能尝试使用一趟扫描实现吗?
    

2. 题目解析

- 题意分解

  1. 本题为删除链表中间的节点
  2. 本题的主要计算是链表遍历
  3. 基本的解法是循环,链表1读一遍,链表2读一遍,所以基本的时间算法复杂度为O(m)

- 优化思路

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

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

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

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

    1. 标准发放是遍历一遍求链表长度,在走到要删除的节点执行删除操作

    2. 使用快慢指针的方式,可以一次扫描完成

    3. 可以用列表结构进行节点删除【注意如果要删除多个节点,列表是最优选择】


- 测量工具

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

3. 代码展开

1) 标准求解【二次遍历】

第一次遍历获得链表长度,第二次遍历完成删除

半生不熟,超过50%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 @staticmethod
 def removeNthFromEnd_base(head, n):
     ilength, tmpNode = 0, head
     while tmpNode:
         ilength += 1
         tmpNode = tmpNode.next
     iPos, target = 0, ilength - n - 1
     if target == -1:
         return head.next
     tmpNode = head
     while iPos != target:
         iPos += 1
         tmpNode = tmpNode.next
     tmpNode.next = tmpNode.next.next
     return head

result = cfp.getTimeMemoryStr(Solution.removeNthFromEnd_base, ahead, 100000)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 removeNthFromEnd_base 的运行时间为 18.01 ms;内存使用量为 4.00 KB 执行结果 = 0

2) 改进版一【快慢指针】

将快慢指针距离调整为n,然后一次遍历完成

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

import CheckFuncPerf as cfp

class Solution:
 @staticmethod
 def removeNthFromEnd_ext1(head, n):
     slownode, fastnode = head, head
     for iIdx in range(n):
         fastnode = fastnode.next
     if not fastnode:
         return head.next
     while fastnode.next:
         slownode = slownode.next
         fastnode = fastnode.next
     slownode.next = slownode.next.next
     return head

result = cfp.getTimeMemoryStr(Solution.removeNthFromEnd_ext1, ahead, 100000)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 removeNthFromEnd_ext1 的运行时间为 10.00 ms;内存使用量为 0.00 KB 执行结果 = 0

3) 改进版二【列表裁剪】

将链表转换为数组,再裁剪链表

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

import CheckFuncPerf as cfp

class Solution:
 @staticmethod
 def removeNthFromEnd_ext2(head, n):
     list_Node = []
     tmpNode = head
     while tmpNode:
         list_Node.append(tmpNode)
         tmpNode = tmpNode.next
     if len(list_Node) < 1:
         return head
     if len(list_Node) == 1:
         return None
     if n == 1:
         list_Node[-n - 1].next = None
     elif n == len(list_Node):
         head = head.next
     else:
         list_Node[-n-1].next = list_Node[-n+1]
     return head

result = cfp.getTimeMemoryStr(Solution.removeNthFromEnd_ext2, ahead, 100000)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 removeNthFromEnd_ext2 的运行时间为 17.01 ms;内存使用量为 904.00 KB 执行结果 = 0

4. 最优算法

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

nums = [ x for x in range(200000)]
def generateOneLinkedList(data):
    head = ListNode()
    current_node = head
    for num in data:
        new_node = ListNode(num)
        current_node.next = new_node
        current_node = new_node
    return head.next
ahead = generateOneLinkedList(nums)
result = cfp.getTimeMemoryStr(Solution.removeNthFromEnd_base, ahead, 100000)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 算法本地速度实测比较
函数 removeNthFromEnd_base 的运行时间为 18.01 ms;内存使用量为 4.00 KB 执行结果 = 0
函数 removeNthFromEnd_ext1 的运行时间为 10.00 ms;内存使用量为 0.00 KB 执行结果 = 0
函数 removeNthFromEnd_ext2 的运行时间为 17.01 ms;内存使用量为 904.00 KB 执行结果 = 0

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

may the odds be ever in your favor ~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何像工程师一样阅读 - 快速阅读技术书籍的9个技巧

0. 目的 在看了 Read Like an Engineer: 9 Tips for Reading Technical Books Fast 之后&#xff0c; 记录一些个人的看法&#xff0c;并在这篇英文文章上作为实验&#xff0c; 记录一下正确的阅读方法。 1. 第一次阅读 1.1 生词表 parcel of the job: 工作中必不可少的部分…

改变AI服务器:探索界面互连芯片技术的创新突破

根据TrendForce的数据&#xff0c;AI服务器的出货量约为130,000台&#xff0c;占全球服务器总出货量的约1%。随着微软、Meta、百度和字节跳动等主要制造商相继推出基于生成式AI的产品和服务&#xff0c;订单量显著增加。预测显示&#xff0c;在ChatGPT等应用的持续需求推动下&a…

【JAVA WEB】盒模型

目录 边框 内边距 基础写法 复合写法 外边距 基础写法 复合写法 块级元素的水平居中 弹性布局 设置行内元素的属性 &#xff0c;span 每一个HTML元素就相当于是一个矩形的“盒子” 这个盒子由以下这几个部分构成&#xff1a; 1.边框 border 2.内容 content 3.内边…

掌握Vue,开启你的前端开发之路!

介绍&#xff1a;Vue.js是一个构建数据驱动的Web应用的渐进式框架&#xff0c;它以简洁和轻量级著称。 首先&#xff0c;Vue.js的核心在于其视图层&#xff0c;它允许开发者通过简单的模板语法将数据渲染进DOM&#xff08;文档对象模型&#xff09;。以下是Vue.js的几个重要特点…

EMC学习笔记(二十三)降低EMI的PCB设计指南(三)

双层板电源分配 1.单点与多点分布2.星型分布3.创建网格平面4.旁路和磁珠5.将噪声保持在芯片附近 tips&#xff1a;资料主要来自网络&#xff0c;仅供学习使用。 1.单点与多点分布 在一个真正的单点配电系统中&#xff0c;每个有源元件都有自己独立的电源和地&#xff0c;这些…

揭开Markdown的秘籍:标题|文字样式|列表

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;Markdown指南、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️Markdown 标题二. ⛳️Markdown 文字样式2.1 &#x1f514;斜体2.2 &…

倍增c++

快速幂 区间最小值&#xff08;用倍增思想去求&#xff09; #include<bits/stdc.h> using namespace std; #define maxn 110000 #define ll long long int n, a[maxn], f[maxn][40]; int query (int l, int r) {int k (int)(log((r - l 1) * 1.0) / log(2.0));retur…

JAVA设计模式之原型模式详解

原型模式 1 原型模式介绍 定义: 原型模式(Prototype Design Pattern)用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型对象相同的新对象。 西游记中的孙悟空 拔毛变小猴,孙悟空这种根据自己的形状复制出多个身外化身的技巧,在面向对象软件设计领…

MySQL ——group by子句使用with rollup

group by 子句使用with rollup关键字之后&#xff0c;具有分组加和的功能。即&#xff1a;在所有的分组记录之后&#xff0c;自动新增一条记录&#xff0c;从全局计算所有记录的数据。 0 问题描述 求出每年的学生平均成绩&#xff0c;及历史至今的平均成绩&#xff0c;结果保留…

机器学习系列——(十一)回归

引言 在机器学习领域&#xff0c;回归是一种常见的监督学习任务&#xff0c;它主要用于预测数值型目标变量。回归分析能够通过对输入特征与目标变量之间的关系建模&#xff0c;从而对未知数据做出预测。 概念 回归是机器学习中的一种监督学习方法&#xff0c;用于预测数值型目…

HarmonyOS 创建components目录 定义全局自定义组件导出供整个项目使用

之前我的文章 harmonyOS 自定义组件基础演示讲解 我们讲解了 自定义组件的基础用法 但是 我们是写在单个page文件中的 这样 我们跨文件使用就很不友好了 如下图 指向 ets目录下 创建一个目录 按我们 前端开发以往的习惯 这个目录要叫 components 专门放组件集合的地方 然后 按…

Windows Server 2025 Hyper-V 新变化

今天简单跟大家聊聊Windows Server 2025 Hyper-V一些新功能新变化&#xff0c;具体如下&#xff1a; 在 VM 之间共享 GPU 随着图形处理器的重要性日益增加&#xff0c;特别是由于它们在 AI 应用程序中的核心作用&#xff0c;Hyper-V 中对 GPU 的现有支持已不再足够。到目前为…

GPT-4模型中的token和Tokenization概念介绍

Token从字面意思上看是游戏代币&#xff0c;用在深度学习中的自然语言处理领域中时&#xff0c;代表着输入文字序列的“代币化”。那么海量语料中的文字序列&#xff0c;就可以转化为海量的代币&#xff0c;用来训练我们的模型。这样我们就能够理解“用于GPT-4训练的token数量大…

【MySQL】MySQL表的增删改查(基础)

MySQL表的增删改查&#xff08;基础&#xff09; 1. CRUD2. 新增&#xff08;Create&#xff09;2.1 单行数据全列插入2.2 多行数据 指定列插入 3. 查询&#xff08;Retrieve&#xff09;3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重&#xff1a;DISTINCT…

数据结构——单向链表和双向链表的实现(C语言版)

目录 前言 1. 链表 1.1 链表的概念及结构 1.2 链表的分类 2. 单链表接口实现 2.1 数据结构设计与接口函数声明 2.2 创建结点&#xff0c;打印&#xff0c;查找 2.3 尾插&#xff0c;头插&#xff0c;尾删&#xff0c;头删 2.4 插入或删除 2.4.1在指定位置后 2.4.2在…

一文讲透Python函数中的形式参数和实际参数

函数参数包括形式参数和实际参数&#xff0c;简称形参和实参。其中形式参数即是在定义函数时函数后面括号中的参数列表&#xff08;parameterlist&#xff09;&#xff0c;比如上一个帖子的示例中的width, length&#xff1b;实际参数则是调用函数时函数后面括号中的参数值&…

【OrangePi Zero2的系统移植】OrangePi Zero2 SDK说明

一、使用环境要求 二、获取Linux SDK 三、首次编译完整SDK 基于OrangePi Zero2的系统移植 之前我们讲解香橙派的使用时&#xff0c; 都是直接在香橙派上进行代码编译&#xff0c; 但在实际的项目开发过程中&#xff0c;更多 的还是使用交叉编译环境进行代码的编译。再编译完成…

学习Android的第八天

目录 Android ImageView 图像视图 ImageView 的基本使用 src属性和background属性的区别 范例 解决 anndroid:blackground 属性拉伸导致图片变形的方法 设置透明度的问题 范例 android:src 和 android:background 结合 范例 Java 代码中设置 blackground 和 src 属性…

【C语言自定义类型详解进阶】结构体(补充结构体的对齐和位段,一口气看完系列,央妈都点赞的博文)

目录 1.结构体 1.1 结构的基础知识 1.2 结构的声明 1.2.1特殊的声明&#xff08;匿名结构体类型&#xff09; 1.3结构体变量的定义 1.4关于匿名结构体类型的补充 1.5结构体的自引用 1.6结构体变量的初始化 2.结构体内存对齐&#xff08;重点&#xff09; 2.1偏移量补…