每日一题--删除链表的倒数第 N 个结点

破阵子-晏殊

燕子欲归时节,高楼昨夜西风。

求得人间成小会,试把金尊傍菊丛。歌长粉面红。
斜日更穿帘幕,微凉渐入梧桐。

多少襟情言不尽,写向蛮笺曲调中。此情千万重。

目录

题目描述:

思路分析:

方法及时间复杂度:

法一 双指针(经典解法)

法二 计算链表长度(暴力解法)

法三 栈

法四 哈希表

法五 vector

个人总结:


 

 题目描述:

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

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

思路分析:

此题要求是删除倒数第N个结点,那么主要的就是找到倒数第N个结点,然后让该节点的前一个指向该结点的下一个。

 那么这道题便有五种以上的解法,核心就是找到要删的那个结点。

方法及时间复杂度:

法一 双指针(经典解法)

定义两指针:fast=head,slow=head。

fast先走n步,然后fast跟slow同时走。

直到fast走到空,此时slow 就到删除的结点。原理:设链表长L,快指针共走L步,慢指针走L-n步。故此方法由法二得来。

 由于这题是删除该结点,这得需要删除结点的前继结点。所以让slow少走一步。可以直接开辟一个虚拟结点让slow=dummy。

 这样solw就可以到达删除结点的前一个结点了。然后像思路分析那样操作。代码如下:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy=new ListNode(0,head);
        ListNode* fast=head,*slow=dummy;
        while(n--){
            fast=fast->next;
        }
        while(fast){
            fast=fast->next;
            slow=slow->next;
        }
        slow->next=slow->next->next;
        ListNode* ans=dummy->next;
        delete dummy;
        return ans;
    }
};

时间复杂度O(L),链表长度为L。

空间复杂度O(1)。

法二 计算链表长度(暴力解法)

遍历链表计算长度,减去n就是正着数的个数,注意的是,如果长度L-n==0就是头删了。代码如下:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int count=0;
        ListNode* cur=head,*pre=head;
        while(cur){
            ++count;
            cur=cur->next;
        }
        if(count==n) return head->next;
        cur=head;
        for(int i=0;i<(count-n)&&cur!=nullptr;++i){
            pre=cur;
            cur=cur->next;
        }
        pre->next=cur->next;
        return head;
    }
};

时间复杂度O(L),链表长度为L。

空间复杂度O(1)。

法三 栈

根据栈的特点先进后出,创建一个虚拟头节点(防止空栈),让所有结点入栈,然后出栈n个结点,此时栈顶元素就是要删除的结点的前一个。

代码如下:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy=new ListNode(0,head);
        stack<ListNode*> st;
        ListNode* cur=dummy;
        while(cur){
            st.emplace(cur);
            cur=cur->next;
        }
        for(int i=0;i<n;++i){
            st.pop();
        }
        ListNode* pre=st.top();
        pre->next=pre->next->next;
        ListNode* ans=dummy->next;
        delete dummy;
        return ans;
    }
};

时间复杂度O(L),链表长度为L。

空间复杂度O(L)。为栈开销

法四 哈希表

主要思想是一样的,查找到删除结点的前一个结点,如果前一个没有结点就头删。

代码如下:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        unordered_map<int,ListNode*> hash;
        ListNode *cur=head;
        int i=0;
        while(cur){
            hash.insert({i++,cur});
            cur=cur->next;
        }
        int target=i-n;
        if(target==0) return head->next;
        //target上一个位置的指针指向下一个
        ListNode* left=hash[target-1];
        left->next=left->next->next;
        return head;
    }
};

时间复杂度O(L),链表长度为L,哈希表查找也为O(L)。

空间复杂度O(L)。哈希表的开销。

法五 vector

与法四思路相同,不多解释。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        vector<ListNode*> ret;
        ListNode* cur=head;
        while(cur){
            ret.emplace_back(cur);
            cur=cur->next;
        }
        int target=ret.size()-n;
        if(target==0) return head->next;
        ListNode* left=ret[target-1];
        left->next=left->next->next;
        return head;
    }
};

时间复杂度O(L),链表长度为L。

空间复杂度O(L)。

个人总结:

大致思路就是找倒数第n个结点,删除结点实现起来其实并不复杂,可以还有更多的方法做这道题。

 

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

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

相关文章

全面(16万字)深入探索深度学习:基础原理到经典模型网络的全面解析

前言 Stacking(堆叠) 网页调试 学习率&#xff1a;它决定了模型在每一次迭代中更新参数的幅度激活函数-更加详细 激活函数的意义: 激活函数主要是让模型具有非线性数据拟合的能力&#xff0c;也就是能够对非线性数据进行分割/建模 如果没有激活函数&#xff1a; 第一个隐层: l…

关于python中的nonlocal关键字

如果在函数的子函数中需要调用外部变量&#xff0c;一般会看见一个nonlocal声明&#xff0c;类似下面这种&#xff1a; def outer_function():x 10def inner_function():nonlocal xx 1print(x)inner_function()outer_function()在这个例子中&#xff0c;inner_function 引用…

[HCIE] IPSec-VPN (IKE自动模式)

概念&#xff1a; IKE&#xff1a;因特网密钥交换 实验目标&#xff1a;pc1与pc2互通 步骤1&#xff1a;R1与R3配置默认路由 R1&#xff1a; ip route-static 0.0.0.0 0.0.0.0 12.1.1.2 R2&#xff1a; ip route-static 0.0.0.0 0.0.0.0 23.1.1.2 步骤2&#xff1a;配ACL…

Java数组的复制、截取(内含例题:力扣-189.轮转数组)

目录 数组的复制、截取&#xff1a; 1、使用Arrays中的copyOf方法完成数组的拷贝 2、使用Arrays中的copyofRange方法完成数组的拷贝 题目链接&#xff1a; 数组的复制、截取&#xff1a; 1、使用Arrays中的copyOf方法完成数组的拷贝 public class Csdn {public static vo…

vscode的下载安装与配置【超详细】

1、下载 进入vscode官网 打开浏览器的下载内容管理&#xff0c;找到vscode下载任务&#xff0c;鼠标放在下载链接上并右击&#xff0c;点击复制链接地址 下载太慢&#xff1f;使用国内镜像 打开新窗口粘贴地址&#xff0c;并将域名改为&#xff1a;vscode.cdn.azure.cn&am…

ZKP11.4 Use CI to instantiate Fiat-Shamir

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 11: From Practice to Theory (Guest Lecturer: Alex Lombardi) 11.4 Use CI to instantiate Fiat-Shamir Avoid Bad Challenges Def: Given false claim x x x and a first message α \alpha α, a challenge β \beta …

JAVA小游戏“简易版王者荣耀”

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 GameFrame 运行类 package com.sxt;import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; im…

java集合,ArrayList、LinkedList和Vector,多线程场景下如何使用 ArrayList

文章目录 Java集合1.2 流程图关系1.3 底层实现1.4 集合与数组的区别1.4.1 元素类型1.4.2 元素个数 1.5 集合的好处1.6 List集合我们以ArrayList集合为例1.7 迭代器的常用方法1.8 ArrayList、LinkedList和Vector的区别1.8.1 说出ArrayList,Vector, LinkedList的存储性能和特性1.…

【室内定位系统源码】UWB超宽带定位技术的特点和应用前景

uwb人员、物品定位系统源码&#xff0c;智慧工厂人员安全管理定位&#xff0c;高精度定位系统源码 UWB超宽带定位技术概念&#xff1a; 超宽带无线通信技术&#xff08;UWB&#xff09;是一种无载波通信技术&#xff0c;UWB不使用载波&#xff0c;而是使用短的能量脉冲序…

解决PDF预览时,电子签章、日期等不显示问题

文章目录 问题描述问题排查问题解决 问题描述 在预览PDF时&#xff0c;部分签章或控件没有显示。如下图&#xff1a; 正确应该要这样&#xff1a; 问题排查 根据网上搜索&#xff0c;排查&#xff0c;我先看看&#xff0c;pdf.worker.js 里的这三行代码&#xff0c;是否已经注…

无需API开发,有赞小程序集成广告推广系统,提升品牌曝光

无需API开发&#xff0c;实现有赞小程序与其他系统的连接 有赞小程序作为一个多功能的电子商务解决方案&#xff0c;为商家提供了无需复杂API开发就可以实现系统连接和集成的便捷途径。通过有赞小程序&#xff0c;商家可以轻松实现与各种系统的数据同步和应用互联&#xff0c;…

【机器学习】聚类(二):原型聚类:LVQ聚类(学习向量量化)

文章目录 一、实验介绍1. 算法流程2. 算法解释3. 算法特点4. 应用场景5. 注意事项 二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 导入必要的库1. LVQ类a. 构造函数b. 闵可夫斯基距离c. LVQ聚类过程e. 聚类结果可视化 2. 辅助函数3. 主函数a. 命令行界面 &#xff…

【MATLAB】VMD分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 VMD&#xff08;Variational Mode Decomposition&#xff09;是一种信号分解方法&#xff0c;基于HHT&#xff08;Hilbert-Huang Transform&#xff0c;希尔伯特-黄变换&#xff09;。HH…

3、点亮一个LED

新建工程 project—>New uVision Project LED介绍 中文名&#xff1a;发光二极管 外文名&#xff1a;Light Emitting Diode 简称&#xff1a;LED 用途&#xff1a;照明、广告灯、指引灯 电路图分析 进制的转换 生成下载文件&#xff1a; 代码 //导包 #inclu…

Javascript每天一道算法题(十八)——矩阵置零-中等

文章目录 1、问题2、示例3、解决方法&#xff08;1&#xff09;方法1——标记数组 1、问题 给定一个 y x x 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 2、示例 示例 1&#xff1a; 输入&#xff1a;matrix [[…

Java 多线程编程

Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每一部分都称作一个线程&#xff0c;并且每个线程定义了一个独立的执行路径。 多线程是多任务的一种特别的形式。多线程比多任务需要更小的开销。 这里定义和线程相关的另一个术语&…

道高一尺,魔高一丈!Python爬虫与反爬虫大战见此回分晓?

文章目录 前言一、重新理解爬虫中的一些概念二、反爬虫的目的三、爬虫与反爬虫大战关于Python及爬虫技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试…

动态规划经典例题leetcode思路代码详解

目录 动态规划基础篇例题 leetcode70题.爬楼梯 leetcode746题.使用最小花费爬楼梯 leetcode198题.打家劫舍 leetcode62题.不同路径 leetcode64题.最小路径和 leetcode63题.63不同路径II 动态规划基础篇例题 这一篇的例题解答是严格按照我上一篇写的动态规划三部曲做的&…

【机器学习】算法性能评估常用指标总结

考虑一个二分问题&#xff0c;即将实例分成正类&#xff08;positive&#xff09;或负类&#xff08;negative&#xff09;。对一个二分问题来说&#xff0c;会出现四种情况。如果一个实例是正类并且也被 预测成正类&#xff0c;即为真正类&#xff08;True positive&#xff0…

【图解系列】一张图带你了解 DevOps 生态工具

一张图带你了解 DevOps 生态工具 ✅ 协作&#xff08;Collaborate&#xff09;&#xff1a;JIRA、Confluence 大家肯定不陌生了&#xff0c;我之前也写过利用 Jekyll 搭建个人博客的帖子。✅ 构建&#xff08;Build&#xff09;&#xff1a;常用的 SCM&#xff08;Software Con…