链表二 链表常见算法题

news2024/9/23 19:24:00

目录

ListNode代码

链表中倒数最后k个结点

描述

        示例1

        示例2

解题思路

AC代码

不借助指针

快慢指针

删除链表中重复的结点

描述

示例1

示例2

解题思路

AC代码

可测试运行代码(需要ListNode代码,在文章开头):

运行结果


​​​​​​​链表一(基本概念和应用场景)+ 链表常见算法题-CSDN博客

ListNode代码


import java.util.Arrays;

public class ListNode {
    int val;
    ListNode next = null;

    public ListNode(int val) {
        this.val = val;
    }

    //遍历链表转换为字符串便于打印
    public String Traversal(ListNode listNode) {
        int[] arr = new int[getLength(listNode)];
        int i = 0 ;
        while (listNode != null){
            arr[i] = listNode.val;
            listNode = listNode.next;
            i++;
        }
        return Arrays.toString(arr);
    }
    // 获取长度
    public int getLength(ListNode head) {
        int length = 0;
        while (head != null) {
            length++;
            head = head.next;
        }
        return length;
    }
}

链表中倒数最后k个结点

描述

输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。

如果该链表长度小于k,请返回一个长度为 0 的链表。

数据范围:0≤n≤105,0≤ai≤109,90≤k≤109

要求:空间复杂度 O(n),时间复杂度O(n)

进阶:空间复杂度 O(1),时间复杂度 O(n)

例如输入{1,2,3,4,5},2时,对应的链表结构如下图所示:

其中蓝色部分为该链表的最后2个结点,所以返回倒数第2个结点(也即结点值为4的结点)即可,系统会打印后面所有的节点来比较。

示例1

输入:{1,2,3,4,5},2

返回值:{4,5}

说明:返回倒数第2个节点4,系统会打印后面所有的节点来比较。

示例2

输入:{2},8

返回值:{}

解题思路

  1. 先算出链表的长度
  2. 算出到倒数第k个节点需要多少步
  3. 将指针移动指定步数,到达指定的节点。返回当前结点。

AC代码

不借助指针

public ListNode FindKthToTail (ListNode pHead, int k) {
        // write code here
        // 求出链表的长度
        int length = getLength(pHead);
        if(length < k){
            return null;
        }
        // 算出链表要走多少步
        int step = length - k;
//        // 定义一个指针
//        ListNode cur = pHead;
        // 移动相应步数找到需要返回的节点
        while(step != 0){
            pHead = pHead.next;
            step--;
        }
        return pHead;
    }
    //
    public int getLength(ListNode head){
        int length = 0;
        while(head != null){
            length++;
            head = head.next;
        }
        return length;
    }

快慢指针

public ListNode FindKthToTailByTwoPointer(ListNode pHead, int k){
        // 定义两个快慢指针
        ListNode fast = pHead;
        ListNode slow = pHead;
        // fast 先走k步
        while(k != 0){
            if (fast != null){
                // fast 往后走
                fast = fast.next;
                k--;
            }else {
                // 如果fast还没走到第k个位置 就是k大于链表长度,返回null
                return null;
            }
        }
        // 因为fast 先走k步,在保证两个指针一起走 他们的距离始终为k,
        // 当fast到链尾的时候 slow所在的位置就是倒数第k个节点
        while (fast != null){
            fast = fast.next;
            slow = slow.next;
        }
        // 
        return slow;
    }

删除链表中重复的结点

描述

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5

数据范围:链表长度满足 0≤n≤1000 ,链表中的值满足 1≤val≤1000

进阶:空间复杂度 O(n) ,时间复杂度 O(n)

例如输入{1,2,3,3,4,4,5}时,对应的输出为{1,2,5},对应的输入输出链表如下图所示:

示例1

输入:{1,2,3,3,4,4,5}

返回值:{1,2,5}

示例2

输入:{1,1,1,8}

返回值:{8}

解题思路

  1. 使用两个工作指针 一个前赴(pre)指针在前,负责构建新的建表,一个当前(cur)指针去找重复节点的值,便于pre去连接。
  2. 总的来说就是去遍历链表,去寻找链表中重复出现的值,然后跳过这些值,使用pre去连接下一个节点值。
  3. 具体步骤如下代码:

AC代码

public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        // 定义一个新的头节点 构建删除重复节点后的链表
        ListNode nHead = new ListNode(0);
        // 前赴指针
        ListNode pre = nHead;
        // 当前结点
        ListNode cur = pHead;
        // 将新的表头与pHead相连
        nHead.next = pHead;
        // 循环条件 要么当前节点为空 需要跳出循环 或者 工作指针到链尾需要跳出循环
        while(cur != null && cur.next != null){
            // 如果当前节点的值和下一个节点的值相等
            if(cur.next !=null && cur.val == cur.next.val ){
                // 持续找到连续重复的值一直移动指针 直到相邻两个节点的值不相等
                while(cur != null && cur.next != null && cur.val == cur.next.val ){
                    // 后移指针 
                    cur = cur.next;
                }
                // 移动到下一个暂时没有重复的节点值的位置
                cur = cur.next;
                // 将pre连接到重复节点的最后一个节点的后一个节点 
                // 这个操作相当于删除当前的有重复值的连续节点 直接连接到下一个暂时不是重复的节点位置
                pre.next = cur;
            }else{
                // pre跟着cur一起移动
                pre = cur;
                cur = cur.next;
            }
        }
        return nHead.next;
    }
}

可测试运行代码(需要ListNode代码,在文章开头):

public static void main(String[] args) {
        ListNode node = new ListNode(1);
        node.next = new ListNode(3);
        node.next.next = new ListNode(3);
        node.next.next.next = new ListNode(5);
        node.next.next.next.next = new ListNode(4);
        String before = node.Traversal(node);
        System.out.println("删除重复节点后的值为: " + before);

        ListNode listNode = deleteDuplication(node);
        String end = listNode.Traversal(listNode);
        System.out.println("删除重复节点后的值为: " + end);
    }

    public static ListNode deleteDuplication(ListNode pHead) {
        // 定义一个新的头节点 构建删除重复节点后的链表
        ListNode nHead = new ListNode(0);
        // 前赴指针
        ListNode pre = nHead;
        // 当前结点
        ListNode cur = pHead;
        // 将新的表头与pHead相连
        nHead.next = pHead;
        // 循环条件 要么当前节点为空 需要跳出循环 或者 工作指针到链尾需要跳出循环
        while(cur != null && cur.next != null){
            // 如果当前节点的值和下一个节点的值相等
            if(cur.val == cur.next.val ){
                // 持续找到连续重复的值一直移动指针 直到相邻两个节点的值不相等
                while(cur.next != null && cur.val == cur.next.val ){
                    // 后移指针
                    cur = cur.next;
                }
                // 移动到下一个暂时没有重复的节点值的位置
                cur = cur.next;
                // 将pre连接到重复节点的最后一个节点的后一个节点
                // 这个操作相当于删除当前的有重复值的连续节点 直接连接到下一个暂时不是重复的节点位置
                pre.next = cur;
            }else{
                // pre跟着cur一起移动
                pre = cur;
                cur = cur.next;
            }
        }
        return nHead.next;
    }

运行结果

图解

未完待续。。。。。。。。。。。。 

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

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

相关文章

windows安装启动mysql8.0版本的简单流程

1.下载mysql8.0.25版本 MySQL :: Download MySQL Community Server (Archived Versions) 2.解压到D盘的mysql文件夹,并修改环境变量 配置环境变量: winr键>输入control system>高级系统设置>点击环境变量 双击path后,新建 将bin目录粘贴进去,再点击确定 在cmd命令行…

萝卜快跑的狠活

萝卜快跑作为百度旗下的自动驾驶出行服务平台&#xff0c;在科技应用上展现了多项领先的技术。以下是萝卜快跑采用的一些主要科技“狠活”&#xff1a; 自动驾驶技术&#xff1a; 萝卜快跑主要使用了百度Apollo的L4级自动驾驶技术&#xff0c;该技术能够应对海量的城市道路场景…

emqx 负载均衡配置 HAProxy 健康检查 轮询 haship

HAProxy配置文件 配置文件&#xff1a; /etc/haproxy/haproxy.cfg 负载均衡参数&#xff1a; 轮询方式轮询注解roundrobin基于权重进行轮叫调度的算法&#xff0c;在服务器的性能分布比较均匀时&#xff0c;这是一种最公平合理&#xff0c;常用的算法。此算法使用较为频…

存储实验:Linux挂载iscsi硬盘与华为OceanStor创建LUN全流程

目录 目的环境规划实验实验流程Centos配置0. 关闭防火墙1. 设置网卡信息2. 配置路由3. iscsiadm连接存储 iSCSI LUN创建&#xff08;以华为OceanStor为例&#xff09;验证1. 验证是否成功2. 开启自动挂载 目的 实现Linux连接iscsi硬盘&#xff0c;同时实现开机自启挂载 环境规…

批量提取PDF中表格内容

1 背景 从PDF文件获取表格中的数据&#xff0c;也是日常办公容易涉及到的一项工作。比如我们想获取某公司年报里面的表格数据&#xff0c;PDF动辄上百页的数据。 2 传统方法 一个一个从PDF表格中复制&#xff0c;然后粘贴到Excel表格中&#xff0c;效率太低了。 3 办公自动…

读懂一本书

各位好,今天我们要分享的这本书叫作《读懂一本书》。 很不好意思,书的作者是我。并不是我写的所有的书我都一定要讲,我也有很多合辑类的书籍是从来不讲的,我讲过《可复制的领导力》,讲过《低风险创业》,还有今天的这本《读懂一本书》,都是我有一些原创的观点和价值在里…

仕考网:公务员考试的录取流程

公务员考试的录取流程分很多个阶段&#xff0c;以下是流程介绍&#xff1a; 1. 报名阶段&#xff1a;考生需根据公布的招聘信息和岗位要求进行报名。 2. 笔试阶段&#xff1a;公务员笔试&#xff0c;包括申论和行测两部分。 3. 成绩公布与面试资格&#xff1a;笔试合格者将获…

通过vagrant与VirtualBox 创建虚拟机

1.下载vagrant与VirtualBox【windows版本案例】 1.1 vagrant 下载地址 【按需下载】 https://developer.hashicorp.com/vagrant/install?product_intentvagranthttps://developer.hashicorp.com/vagrant/install?product_intentvagrant 1.2 VirtualBox 下载地址 【按需下载…

数据说话,效益为王:构建高效精益生产KPI监控体系

一、精益生产和KPI指标管理 在智慧工厂的蓝图中&#xff0c;精益生产已从抽象概念升华为一种深邃的经营哲学&#xff0c;它崇尚的是资源利用的极致效率——以最精简的投入&#xff0c;撬动最大化的产出价值。其核心精髓&#xff0c;在于不遗余力地剔除任何形式的冗余与浪费&am…

python基础语法 005 函数1-1

1 函数 1.1 什么是函数 指&#xff1a;输入一定的数据以后&#xff0c;能根据里面的执行步骤&#xff0c;算出一些数据的值&#xff1b;得到相关的数据&#xff0c;获取对于的输出值。 存储指定功能的程序&#xff0c;进行相应的复用 解释&#xff1a; 洗衣服 》输入值&…

【简历】兰州某大学一本硕士:面试通过率基本是为0

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一个一本硕士的Java简历&#xff0c;那这个简历因为学校本身&#xff0c;它是一个一本的硕士&#xff0c;我们一般认为这一本硕士&a…

数据结构之顺序存储线性表实现详解与示例(C,C#,C++)

文章目录 一、顺序存储线性表的基本概念二、顺序存储线性表的实现1、数据结构定义2、初始化3、添加元素4、访问元素5、修改元素6、删除元素7、销毁 三、示例C语言示例C#语言示例C语言示例 顺序存储线性表是一种基本的数据结构&#xff0c;它将线性表的元素按照一定的顺序存放在…

TCP协议的三次握手和四次挥手(面试)

三次握手 首先可以简单的回答&#xff1a; 1、第一次握手&#xff1a;客户端给服务器发送一个 SYN 报文。 2、第二次握手&#xff1a;服务器收到 SYN 报文之后&#xff0c;会应答一个 SYNACK 报文。 3、第三次握手&#xff1a;客户端收到 SYNACK 报文之后&#xf…

windows单机版mongodb安装

1、先从官网下载安装包官网下载地址 2.本地解压并创建目录 2.1创建data和log目录 2.2创建mongodb.cfg # mongod.conf# for documentation of all options, see: # http://docs.mongodb.org/manual/reference/configuration-options/# Where and how to store data. storag…

Docker基本管理1

Docker 概述 Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源。 Docker是在Linux容器里运行应用的开源工具&#xff0c;是一种轻量级的“虚拟机”。 Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的、自给自…

143. 最长同值路径(卡码网周赛第二十五期(23年B站笔试真题))

题目链接 143. 最长同值路径&#xff08;卡码网周赛第二十五期&#xff08;23年B站笔试真题&#xff09;&#xff09; 题目描述 给定一个二叉树的 root &#xff0c;返回最长的路径的长度&#xff0c;这个路径中的每节点具有相同值。这条路径可以经过也可以不经过根节点。两个…

Wifi贴码推广怎么加入?如何提高收益

自Wifi贴码鼻祖微.火于2021年6月推出全球第一张共享WIFI贴码以来&#xff0c;wifi贴码项目便一直是有入局意向的创业者们的重点关注对象之一。在此背景下&#xff0c;以wifi贴码推广怎么加入为代表的问题更是成为了相关创业者社群中的讨论热点。 事实上&#xff0c;对于尚未入局…

端侧智能为什么有前途

年前陆续和很多小伙伴聊过端侧智能的价值&#xff0c;吹捧的、贬低的都有&#xff0c;各自也都有自己的理由。这里&#xff0c;谨作为利益相关方&#xff0c;分享一下自己对端侧智能的看法&#xff0c;尝试回答端侧智能有没有用、为什么有用和该怎么用的问题。文章不含技术干货…

Java BigInteger 类

目录 BigInteger 1. 如何获取一个BigInteger类型的对象&#xff1f; &#xff08;1&#xff09;构造方法 &#xff08;2&#xff09;静态方法 2. 常用方法 BigInteger 可以用来表示很大很大的数&#xff0c;有多大都可以。通过创建对象调用相应的方法。详见&#xff1a;…

2024年高职云计算实验室建设及云计算实训平台整体解决方案

随着云计算技术的飞速发展&#xff0c;高职院校亟需构建一个与行业需求紧密结合的云计算实验室和实训平台。以下是针对2024年高职院校云计算实验室建设的全面解决方案。 1、在高职云计算实验室的建设与规划中&#xff0c;首要任务是立足于云计算学科的精准定位&#xff0c;紧密…