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

news2024/10/6 1:38:15

破阵子-晏殊

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

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

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

目录

题目描述:

思路分析:

方法及时间复杂度:

法一 双指针(经典解法)

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

法三 栈

法四 哈希表

法五 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个结点,删除结点实现起来其实并不复杂,可以还有更多的方法做这道题。

 

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

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

相关文章

01 _ 高并发系统:它的通用设计方法是什么?

我们知道&#xff0c;高并发代表着大流量&#xff0c;高并发系统设计的魅力就在于我们能够凭借自己的聪明才智设计巧妙的方案&#xff0c;从而抵抗巨大流量的冲击&#xff0c;带给用户更好的使用体验。这些方案好似能操纵流量&#xff0c;让流量更加平稳地被系统中的服务和组件…

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

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

php订单发起退款(余额和微信支付)

index.html <a class="btn btn-danger btn-change btn-tuikuan btn-disabled" href="javascript:;"><i class="fa fa-tuikuan"></i> 订单退款</a>-->order.js // 为表格绑定事件Table.api.bindevent(table);//退款…

Android : Intent(意图)_页面跳转、传递数据_简单应用

示例图&#xff1a; MainActivity.java package com.example.myintent;import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContract; import andro…

【Web】CmsEasy 漏洞复现

访问主页 到处点一点没啥发现 扫目录 访问/admin 账号密码都是admin admin,不知道为什么&#xff0c;这里就先当作是默认吧 &#xff08;其实都是信息检索&#xff0c;能在网上搜到就行hhh&#xff09; 登录成功 看到左边列表有模板&#xff0c;心里大概有数了哈 进行一波历…

不要再往下翻了,你要的女宝穿搭我都有哦

分享女儿的睡衣穿搭 清新自然的浪漫紫 一眼就击中了我的心巴 软糯亲肤上身体验感超赞 轻松自在无束缚 防风又保暖&#xff0c;居家外出都可哦

Python 安装django-cors-headers解决跨域问题

一、PythonCorsHeaders概念 PythonCorsHeaders是一个轻量级的Python工具&#xff0c;用于解决跨域HTTP请求的问题。它允许你指定哪些网站或IP地址可以访问你的站点&#xff0c;并控制这些站点可以访问哪些内容。 现代网站越来越多地使用Ajax技术&#xff0c;使得浏览器能够从不…

RK3588硬编解码MPP环境配置

1. 简介 瑞芯微提供的媒体处理软件平台&#xff08;Media Process Platform&#xff0c;简称 MPP&#xff09;是适用于瑞芯微芯片系列的 通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理&#xff0c;其目的是为了屏蔽不 同芯片的差异&#xff0c;为使用者…

零基础学python第一天||数和四则运算

数和四则运算 一提到计算机&#xff0c;当然现在更多人把她叫做电脑&#xff0c;这两个词都是指computer。不管什么&#xff0c;只要提到她&#xff0c;普遍都会想到她能够比较快地做加减乘除&#xff0c;甚至乘方开方等。乃至于&#xff0c;有的人在口语中区分不开计算机和计…

科研/比赛必备工具及系列笔记集合

科研/比赛必备工具及系列笔记集合 零、前言一、常用工具系列1.1 笔记平台使用感受系列1.2 常用开发平台系列 二、论文系列2.1 检索工具系列2.2 投稿调研系列2.3 常见国际期刊/会议2.4 常见中文核心期刊/会议 三、文献系列3.1 画图工具系列3.2 翻译工具系列3.3 英文纠正系列3.4 …

Vue + Element UI 实现复制当前行数据功能及解决复制到新增页面组件值不更新的问题

文章目录 引言第一部分&#xff1a;复制当前行数据功能的实现1.1 环境准备1.2 创建表格并渲染数据1.3 解决复制的数据不更新问题 第二部分&#xff1a;拓展知识2.1 Vue的响应性原理2.2 Element UI的更多用法 结语 Vue Element UI 实现复制当前行数据功能及解决复制到新增页面组…

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…

初出茅庐的小李之C语言必备知识预处理

编译预处理 编译预处理就是在编译源代码之前进行的一系列处理&#xff0c;将源程序中的一些特殊命令进行展开或处理&#xff0c;生成扩展的源代码。这些特殊命令通常以“#”开头&#xff0c;占单独的行&#xff0c;语句尾部不需要加分号。 宏定义 (#define)是一种常见的编译…

Leetcode—55.跳跃游戏【中等】

2023每日刷题&#xff08;四十&#xff09; Leetcode—55.跳跃游戏 贪心法实现代码 #define MAX(a, b) ((a > b)? (a): (b))bool canJump(int* nums, int numsSize) {int k 0;for(int i 0; i < numsSize; i) {if(i > k) {return false;}k MAX(k, i nums[i]);}r…

[架构之路-251]:目标系统 - 设计方法 - 软件工程 - 软件建模 - 什么是建模,什么是软件系统建模?软件系统阶段性建模?正向建模与反向建模?

目录 前言&#xff1a; 一、什么是建模 1.1 什么是建模 1.2 常见的建模的方式与种类 二、什么是软件系统建模 2.1 软件系统建模的概念 2.2 软件系统常见的三种建模方法和手段 2.3 软件系统建模的常见工具 三、软件系统阶段性建模 3.1 软件工程在不同阶段对软件系统进…

竞赛选题 题目:基于python的验证码识别 - 机器视觉 验证码识别

文章目录 0 前言1 项目简介2 验证码识别步骤2.1 灰度处理&二值化2.2 去除边框2.3 图像降噪2.4 字符切割2.5 识别 3 基于tensorflow的验证码识别3.1 数据集3.2 基于tf的神经网络训练代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于pyt…

[多线程】线程安全问题

目录 1.举个栗子 2.线程安全的概念 3.线程不安全的原因 3.1原子性 3.2Java内存模型&#xff08;jvm&#xff09; 3.3代码重排序 4.解决线程的不安全问题-&#xff08;synchronized&#xff09; ​编辑 4.1sychronized的特性 4.2刷新内存 4.3可重入 5.synchornized使…

【nacos】配置使用

nacos配置 遇见的问题 代码启动成功&#xff0c;但是配置文件未生效 观察报错 无报错&#xff0c;也看到了加载的配置文件路径&#xff0c;但是配置未生效 [main] [TID: N/A] c.a.c.n.refresh.NacosContextRefresher : [Nacos Config] Listening config: dataIda-servi…

【docker】docker安装与优化

目录 一、安装Docker 1、关闭防火墙 2、安装依赖包 3、设置阿里云镜像源 4、安装Docker-CE社区版并设置为开机自启动 5、查看Docker信息 二、设置镜像加速 1、申请加速地址 2、实现加速操作 三、网络优化 1、如何网络优化 2、具体操作 四、docker-server端配置文件…

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 …