删除链表的倒数第k个结点

删除链表的倒数第k个结点

问题重述:

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

示例 1:

删除链表的倒数第k个结点
输入:head = [1,2,3,4,5], k = 2
输出:[1,2,3,5]

示例 2:

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

示例 3:

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

提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <="30</code"><!--=-->
  • 0 <= node.val <="100</code"><!--=-->
  • 1 <= k <="sz</code"><!--=-->

问题分析:

本题要求删除倒数第k个结点,重要的是获取删除结点的前一个结点,将该节点的下一个结点指向要删除的节点的下一个结点,常规思路是遍历链表,获得链表长度,然后根据链表长度找到要删除的结点,这种方法需要遍历两次链表。使用双指针的方法可以做到一次遍历就能够找到结点。使用双指针,一个指针从头开始一个指针从第k个开始,然后两个指针一起向后遍历,当快指针到达链表尾部的时候,慢指针对应的刚好是倒数第k+1个结点

解法:

链表遍历、双指针(一次遍历)

解题:

代码:
package test.linklist;
/**
 *
 * @author FOLDN
 * 从长度为n的链表中,删除倒数第k个结点
 *
 */
public class DeleteKthNode {
    public static void main(String[] args) {

    }
    public static Node deleteKthNode(Node head,int k) {
        /*
        if(k < 1 || head == null) {
            return head;
        }
        // 方法一,直接遍历链表
        // 记录链表的头,因为最后要返回链表的头
        Node linkedList = head;
        while(linkedList != null) {
            // 第一次遍历链表,每经过一个结点,k-1,遍历到最后k = k-n
            k = k-1;
            linkedList = linkedList.next;
        }
        // 遍历完链表后,k有三种情况,分别是等于0,大于0,小于0
        // k大于0,说明需要删除的结点不存在于链表中,不需要处理,直接返回链表即可
        // k等于0,说明要删除的是链表的头节点
        if(k == 0) {
            // 删除头节点然后返回链表
            head = head.next;
        }
        // k小于0,需要再次进行遍历确定要删除的结点
        if(k < 0) {
            // 第二次遍历需要注意的是此时的linkedList对应的是最后的结点,所以需要重新赋值
            linkedList = head;
            while(k != 0) {
                k = k+1;
                linkedList = linkedList.next;
            }
            // 删除结点
            linkedList.next = linkedList.next.next;
        }
        return head;
        */
        // 方法二,使用双指针,只需要使用一次循环
        if(k < 1 || head == null) {
            return head;
        }
        Node fast = head;
        Node slow = head;
        for(int i = 0;i < k; i++) {
            fast = fast.next;
        }
        // 这一步是为了当删除的结点是头结点的时候,可以正常返回
        if(fast == null) {
            return head.next;
        }
        while(fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return head;
    }

}
代码解析:

链表遍历相当简单,就是先遍历一般确定长度,然后通过长度确定要删除的节点的前一个结点,然后第二次遍历找到要要删除的结点的前一个结点,对链表进行更改

本题我们使用快慢双指针对链表进行遍历,一遍遍历即可确定要删除的结点。首先让快指针fast先向前移动k个位置,此时让fast指针和slow指针一起向后遍历,当fast指针遍历完最后一个节点(即此时的fast结点对应的是链表最后一个结点对应的next,为null)的时候,slow结点对应的结点就是要删除的结点。 为了简便删除对应结点,我们可以一开始创建一个哑结点,将该节点的next设为head,这样我们可以处理直接处理当要删除的结点为头节点的问题,并且找到的结点是要删除的节点的下一个结点

总结:

快慢双指针一般用于倒数的元素的处理或者检测会回文序列

Original: https://www.cnblogs.com/foldn/p/15918689.html
Author: foldn
Title: 删除链表的倒数第k个结点

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/579770/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • java学习第二天

    Day02 &#x7B2C;&#x4E8C;&#x5929;&#x4E3B;&#x8981;&#x4E86;&#x89E3;…

    Java 2023年6月8日
    061
  • 用户名密码年龄的校验

    用户名: 密码: 确认密码: 年龄: //校验用户名 function usernamecheck(){ //获取dom var username = document.getEl…

    Java 2023年6月7日
    075
  • 面向对象编程-基础

    面向对象是一种”建模思想” 把现实中的各种事物”虚拟化到程序中”(定义类就是一种封装) 类:对现实生活中一类具有共同属性和行为的事物…

    Java 2023年6月8日
    075
  • 谷粒商城(无CURD代码)

    写在开头: 这份笔记仅仅记录了一些环境搭建以及基础篇中一些技术的使用,基本的CURD大部分没有记录,参考了很多网友的博客。若有冒犯,请联系我删除。参考文档见下: 本博客为自己随笔记…

    Java 2023年6月13日
    069
  • Flutter Could not resolve project :path_provider_macos.

    错误信息: 如果是在纯Flutter项目执行,这样基本就修复了。 如果是Flutter以Module形式被原生项目依赖,那么有可能不行,这时候,就按报错提示修复,原生项目找到 cs…

    Java 2023年5月29日
    0181
  • RabbitMQ 工作队列

    每日一句 如果你执意追逐我的幻影,迟早会被真正的我打败。 https://www.ylcoder.top/post/1649241412 概述 工作队列(又称任务队列)的主要思想是…

    Java 2023年6月9日
    0110
  • 【Oracle初学者】ORA-01034: ORACLE not available

    系统报错代码 ORA-01034: ORACLE not available 出现原因 //&#x5728;&#x542F;&#x52A8;&#x5…

    Java 2023年6月13日
    068
  • 社交网站后端项目开发日记(二)

    本项目目标是开发一个社区网站,拥有发帖、讨论、搜索、登录等一个正常社区拥有的功能。涉及到的版本参数为: JDK1.8 Maven3.8.1(直接集成到IDEA) Springboo…

    Java 2023年6月7日
    078
  • AJAX学习(1)

    基础确认:HTML、CSS、JavaScript AJAX可以: Ajax 的核心是 XMLHttpRequest 对象,用于和服务器交换数据。 xmlhttp.open(&quo…

    Java 2023年6月9日
    096
  • 00MQTT【目录】

    MQTT posted on2022-06-04 14:00 格物致知_Tony 阅读(11 ) 评论() 编辑 Original: https://www.cnblogs.com…

    Java 2023年5月29日
    079
  • Java获取本机IP

    import lombok.extern.slf4j.Slf4j; import org.junit.Test; import java.net.Inet4Address; imp…

    Java 2023年5月29日
    089
  • JAVA入门基础_从零开始的培训_Linux基础入门理解

    Linux操作系统 Linux操作系统的应用领域 VMware虚拟机的安装 在BIOS中开启操作系统的虚拟化 虚拟机的实际安装 Centos7.6版本的安装 下载Centos操作系…

    Java 2023年6月9日
    075
  • 如何在Docker容器中使用Arthas

    Arthas(阿尔萨斯) 能为你做什么? Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。当你遇到以下类似问题而束手无策时, Arthas可以帮助你解决: 这…

    Java 2023年6月9日
    094
  • Java连载155-IO总结(二)

    一、四种方式分别举例 1.FileInputStream &#xA0;&#xA0;InputStream&#xA0;is&#xA0;=&#x…

    Java 2023年6月13日
    078
  • Android-Java-接口Interface

    接口Interface 与 抽象类不同: 抽象类关注的是事物本质,例如:水果Fruit 属于抽象的,说去买水果 是模糊的概念 是抽象的概念 不具体,到底买什么水果不知道,而水果包含…

    Java 2023年5月29日
    080
  • 反射

    快速入门: re.properties&#x6587;&#x4EF6;&#xFF1A; classfullpath=com.example.Cat meth…

    Java 2023年6月5日
    090
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球