【算法刷题】链表笔试题解析(1)

 

一、链表分割

题目描述:

链接:链表分割

d908ed776515446ba1ee0ca64e55793b.png

题目分析:

        这题直接处理并不好做,我们可以构建前后两个链表,将小于x值的结点放在链表a内,将其它结点放在链表b内,这样将原链表遍历完后,原链表就自然地分成了两部分,最后将两个链表拼接起来就行了。

如果你以为这题到这里就完了,那这题就不会被分在“较难题”里了

        做算法题,我们一定要细心,要考虑好程序可能会面临的所有情况,仔细梳理一下,你会发现这道题主要会有四种情况:

1、给定链表为空

2、链表中的值有大于x的,也有小于x的

3、链表中所有结点的值都大于x

4、链表中所有节点的值都小于x

这时问题就很明显了,我们之前的思路只能处理第二种情况,遇到其它情况的时候就会出现问题。

比如在第三种情况下,由于没有小于x的结点,所以链表a的头尾指针都不能指向具体的结点,这时如果再通过a链表的尾节点指向b链表的方式链接,就会出现空指针异常导致程序出错了

因此我们还需要分别处理其它三种情况:

1、因为链表为空,所以不需要处理,直接返回头结点即可

3、此时a链表的头指针应该为空,只需要返回b链表的头结点即可

4、此时b链表为空,正常让a的尾结点指向b的头,直接返回头结点即可

注意:二三种情况时需要将b的尾结点的后驱结点置空,这样才能构建一个正常的单链表


代码实现:

public class Partition {
    public ListNode partition(ListNode pHead, int x) {
        // write code here
        if(pHead==null){
            return pHead;
        }
        ListNode as=null;
        ListNode ae=null;
        ListNode bs=null;
        ListNode be=null;
        ListNode cur=pHead;
        while(cur != null){
            if(cur.val<x){
                if(as==null){
                    as=cur;
                    ae=cur;
                }else{
                    ae.next=cur;
                    ae=ae.next;
                }         
            }else{
                if(bs==null){
                    bs=cur;
                    be=cur;
                }else{
                    be.next=cur;
                    be=be.next;
                } 
            }
            cur=cur.next;
        }
        if(as==null){
            be.next=null;
            return bs;
        }
        ae.next=bs;
        if(bs!=null){
            be.next=null;
        }
        return as;
    }
}

二、链表的回文结构

题目描述:

链接:链表的文结构

da5cea59b7bc46d2923b22b02920ddaf.png

题目分析:

有些人看到这题的第一想法可能是遍历一遍链表,将链表中的值都存在一个数组中,然后用数组的处理方法来判断是否回文,从而大大简化题目难度。

这的确是一个不错的思路,但你有没有发现题目还有以下要求:

时间复杂度为O(n),额外空间复杂度为O(1)的算法

如果你不知道什么是时间复杂度和空间复杂度的话,可以看看博主的这篇文章:博客链接

很明显,数组的空间复杂度是O(N),不符合题目要求,出题者明显不想让你用这么粗暴的方式解题

这里博主提供一个简单的思路:

我们可以先将链表反转,然后判断两个链表相应位置上的值是否相等即可

 

代码实现:

public class PalindromeList {
    public boolean chkPalindrome(ListNode A) {
        // write code here
        if(A==null||A.next==null){
            return true;
        }
        ListNode cur1=A.next;
        ListNode cur2=A.next;
        ListNode head=A;
        head.next=null;
        while(cur1!=null){
            cur2=cur1.next;
            cur1.next=head;
            head=cur1;
            cur1=cur2;
        }
        while(A!=null){
            if(A.val!=head.val){
                return false;
            }
            A=A.next;
            head=head.next;
        }
        return true;
    }
}

三、链表的中间节点

题目描述:

链接: 链表的中间节点

52df901407e04f78afeb34a52a34d5b9.png

题目分析:

我们可以用快慢指针的方法,定义一个快指针fast每次走两步,再定义一个慢指针每次走一步,这样在快指针遍历完链表时,慢指针就正好位于中间位置了

注意:链表的长度可能是奇数也可能是偶数,当结点数为奇数时,fast是走不到最后一个的,如果强行每次都走两步的话最后会出现空指针异常,不过仔细观察你会发现,当fast走到倒数第二位时,slow就刚好位于中间结点了,因此我们只要改变一下循环退出条件即可

代码实现:

class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode cur1=head;
        ListNode cur2=head;
        while(cur1 !=null&&cur1.next!=null){
            cur1=cur1.next.next;
            cur2=cur2.next;
        }
        return cur2;
    }
}

 

四、相交节点

题目描述:

链接:相交节点

d5e2d95c48bd4b1aa612c11944789f5c.png

 

题目分析:

        如果两个链表等长的情况下,这题就非常简单了,只需要同时让指针a、b分别从两个链表的头结点出发,判断是否有结点相等即可,但显然,两个链表的长度未必是相等的。

        这时我们可以先让指针a、b分别遍历两个链表,直到有一个链表被遍历完后,这时长链表指针与长链表尾结点的距离正好是两个链表长度的差值,这时再令一指针x指向长链表的头结点,再一次让之前没遍历完的指针y与新指针x进行遍历,直到老指针y指向长链表的尾结点,这时x与长链表的尾结点的距离正好等于短链表的长度,接着就可以用处理两个等长链表的方式来处理了


代码实现:

public class Solution {
        if(headA==null&&headB==null)return null;
        ListNode cur1=headA;
        ListNode cur2=headB;
        while(cur1!=null&&cur2!=null){
            cur1=cur1.next;
            cur2=cur2.next;
        }
        if(cur1==null){
            cur1=headB;
        }else{
            cur2=headA;
        }
        while(cur1!=null&&cur2!=null){
            cur1=cur1.next;
            cur2=cur2.next;
        }
        if(cur1==null){
            cur1=headB;
        }else{
            cur2=headA;
        }
        while(cur1!=null&&cur2!=null){
            if(cur1==cur2){
                return cur1;
            }
            cur1=cur1.next;
            cur2=cur2.next;
        }
        return null;
    }

 

 

五、返回倒数第k个节点

题目描述:

链接:返回倒数第k个节点

ba9d2323bd824f7f842222b741a418a8.png

题目分析:

我们可以定义两个指针,先让指针1遍历链表,同时记录指针走过的步数s,当s=k时,开始让指针2从头结点开始遍历链表,当指针1指向链表的尾结点时,指针2所指向的结点就是倒数第k个结点了

注意:可能出现k值大于链表长度或k值小于零的情况,

当k<0时,题目显然是无解的,直接return-1即可

当k大于链表长度时,我们可以通过记录指针1走过的步数s的大小来判断,如果指针1遍历完链表时,s任小于k,就说明k值超过了链表的长度,直接return -1即可


代码实现:

public class Solution {
    public int kthToLast(ListNode head, int k) {
        if (k < 0) {
            return -1;
        }
        ListNode cur1=head;
        ListNode cur2=head;
        int s=0;
        while(cur1!=null){
            cur1=cur1.next;
            if(s==k){
                cur2=cur2.next;
            }else{
                s++;
            }
        }
        if(s<k){
            return -1;
        }else{
            return cur2.val;
        }
    }
}

 

总结

那么本篇文章就到此为止了,如果觉得这篇文章对你有帮助的话,可以点一下关注和点赞来支持作者哦。作者还是一个萌新,如果有什么讲的不对的地方欢迎在评论区指出,希望能够和你们一起进步✊

6d1311864a3f47b8a5ba9bb8a3f457cc.png

 

 

 

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

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

相关文章

OSCP靶场--image

OSCP靶场–image 考点(CVE-2023-34152 suid strace提权) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap -Pn -sC -sV 192.168.178.178 --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-27 23:43 EDT Nmap scan report for 192.168.178.17…

手机照片恢复:两种方法轻松找回您的珍贵照片!

我们的日常生活中&#xff0c;苹果手机已经成为了记录珍贵时刻的得力工具&#xff0c;而其中最重要的要数照片了。然而&#xff0c;有时候不可避免地会出现误删照片的情况&#xff0c;可能是因为手误、设备故障或其他原因。 当您发现重要的照片不见了&#xff0c;往往会感到焦…

「18」如何让你直播间增加高级质感,效果滤镜是你不二选择?

「18」效果滤镜给你的布景增加质感&#xff0c;更具视觉效果 首先&#xff0c;安装&#xff08;模糊滤镜的‘streamfx’&#xff09;安装包。安装成功后&#xff0c;StreamFX 会出现在 OBS 的菜单栏上。在OBS软件里滤镜可分为效果滤镜和音视频滤镜。 一、音视频滤镜 在选择「…

yolov8 pose keypoint解读

yolov8进行关键点检测的代码如下&#xff1a; from ultralytics import YOLO# Load a model model YOLO(yolov8n.pt) # pretrained YOLOv8n model# Run batched inference on a list of images results model([im1.jpg, im2.jpg]) # return a list of Results objects# Pr…

阿里云效CICD流水线提交前后端项目

后端 一、新建流水线 1进入流水线 2新建流水线 3选择流水线模板 二、上传后端项目 1 将后端项目发布至代码仓库后&#xff0c;在流水线中选择流水线源 我们在选择流水线源之后会出现扫描失败的情况 查看日志发现是因为我们的项目是多模块项目&#xff0c;再扫描的时候无法在…

浏览器扩展程序增加 vue_dev_tools 调试工具

1、引言 在做 Vue 项目的开发时&#xff0c;我们经常需要在页面上调试&#xff0c;接下来介绍如何在浏览器扩展程序增加 vue_dev_tools 调试工具。 Download the Vue Devtools extension for a better development experience 翻译&#xff1a;下载Vue Devtools扩展以获得更好…

C语言例4-30:将一个正整数的各位数字逆序输出

算法分析&#xff1a; 提取某一个正整数的最末一位数字&#xff0c;采用取模10的余数获得&#xff0c;以此类推即可。 代码如下&#xff1a; //将一个正整数的各位数字逆序输出 #include<stdio.h> int main(void) {int i,r;printf("输入一个正整数&#xff1a; \…

地方废物回收机构管理的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 目录 1. …

雷尼绍 VIONiC高精度光栅尺品助力高精度运动控制系统

随着科技的不断进步&#xff0c;对运动控制精度的要求不断提高。雷尼绍Renishaw推出的VIONiC系列是一款超高精度、超小型的一体化数字增量式光栅&#xff0c;可提供直接的数字位置反馈&#xff0c;具有卓越的测量性能、极高的运行速度和可靠性&#xff0c;成为高精度运动控制系…

C语言-Win11安装古老的VC6.0

win11安装VC6 有些学校一直还在使用VC6.0&#xff0c;我们尝试在Win1 下安装这个老古董&#xff0c;以下是在win11下安装VC6.0的方法。 点击安装文件 输入产品序列号 修改公共安装文件夹 如果C盘空间足够可以不用修改。 此处会发现鼠标一直在转圈不能完成更新系统&#xff0c;可…

领导驾驶舱下钻404问题解决

领导驾驶舱下钻404问题解决 问题 领导驾驶舱点击下钻页面 报404, 涉及到学工系统和sso认证系统 思路 传参 https://xxx:9007/getLoginUrl 转发到 https://xxx/getLoginUrl 修改nginx配置 location /getLoginUrl {proxy_pass http://127.0.0.1:80;}报了500错误 清理缓存后…

9.windows ubuntu 子系统,centrifuge:微生物物种分类。

上次我们用了karken2和bracken进行了物种分类&#xff0c;这次我们使用centrifuge. Centrifuge 是一种用于快速和准确进行微生物分类和物种鉴定的软件。其主要功能包括&#xff1a; 快速分类和物种鉴定: Centrifuge 可以对高通量测序数据&#xff08;如 metagenomic 或 RNA-Se…

JAVA------基础篇

java基础 1.JDK JDK :java development kit JRE&#xff1a;java runtime environment JDK包含JRE java跨平台&#xff1a;因为java程序运行依赖虚拟机&#xff0c;虚拟机需要有对应操作系统的版本&#xff0c;而jre中有虚拟机。 当你想要在Linux系统下运行&#xff0c;则需要…

JavaScript 权威指南第七版(GPT 重译)(四)

第九章&#xff1a;类 JavaScript 对象在第六章中有所涉及。该章将每个对象视为一组独特的属性&#xff0c;与其他对象不同。然而&#xff0c;通常有必要定义一种共享某些属性的对象类。类的成员或实例具有自己的属性来保存或定义它们的状态&#xff0c;但它们还具有定义其行为…

vue3+vite - 报错 import.meta.glob() can only accept string literals.(详细解决方案)

报错说明 在vue3+vite项目中,解决报错: [plugin:vite:import-analysis] import.meta.glob() can only accept string literals. 如果我们报错差不多,就可以完美搞定这个错误。 解决教程 这个错误,是因为

3GPP 协议资料学习和文档下载

一、登录3GPP官网 3GPP – The Mobile Broadband Standard 二、选择Specifications Per TSG Round 三、选择ftp下载路径 四、选择不同阶段的3GPP协议 包含了从1999年到R18,甚至更新到当前最新的协议。 五、查看对应版本的LTE或者5G NR协议 其中LTE射频相关章节为36.521系列&…

进销存记账软件有哪些?中小商户的进销存记账管理软件选购指南

进销存记账软件已经成为众多实体店不可或缺的管理工具。利用这类软件&#xff0c;实体店能够解决手工记账效率低下、对账繁琐且容易出错等问题。 然而&#xff0c;许多实体店都是小本经营&#xff0c;对于进销存记账软件的选择缺乏经验&#xff0c;导致随意选购的结果往往令人…

C++开发基础理解std::string 对象的生命周期,避免悬空指针或内存访问错误

一、字符串的两种类型互换 在C开发中&#xff0c;const char * 和 std::string 是用于表示字符串的两种不同类型。它们之间可以相互转换。但是需要注意const char * 和 std::string 的互换场景错误。 const char * 到 std::string 的转换&#xff1a; 可以使用 std::string 的…

保研线性代数机器学习基础复习1

1.什么是代数&#xff08;algebra&#xff09;? 为了形式化一个概念&#xff0c;构建出有关这个概念的符号以及操作符号的公式。 2.什么是线性代数&#xff08;linear algebra&#xff09;&#xff1f; 一项关于向量以及操作向量的公式的研究。 3.举一些向量的例子&#x…

使用 Clip 反推提示词报<error>解决方案

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 大家好&#xff0c;我是水滴~~ 本文主要介绍在使用 Stable Diffusion WebUI 中使用图生图中的“使用 Clip 反推提示词”时报了<error>异常的解决…