Java-数据结构-链表-习题(三)(๑´ㅂ`๑)

news2024/11/10 6:32:10

文本目录:

​❄️一、习题一:

    ▶ 思路:

  ▶ 代码:

​❄️二、习题二:

  ▶ 思路:

  ▶ 代码:

​❄️三、习题三:

  ▶ 思路:

  ▶ 代码:

​❄️四、习题四:

        ▶ 思路:

     ▶ 代码:

​❄️五、习题五:

  ▶ 思路:     

  ▶ 代码: 

 ​❄️六、习题六:

     ▶ 思路:

  ▶ 代码:

​❄️七、习题七:

     ▶ 思路:     

  ▶ 代码: 

​❄️总结:


❄️一、习题一:

☑ 题的链接:

     移除链表的元素

    思路:

这个题呢,和我们在自实现单链表的时候呢,里面的删除所有的val这个值的节点的操作是类似的。我们在重新分析一下:

我们直接来看思路图:

  ▶ 代码:

OK,我们的这个题的思路已经分写完成了,接下来我们来看看代码如何实现的:

public ListNode removeElements(ListNode head, int val) {
        if (head == null) {
            return head;
        }
        ListNode prev = head;
        ListNode cur = head.next;
        while(cur != null) {
            if (cur.val == val) {
                prev.next = cur.next;
                cur = cur.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        //判断head的val是否和val相等
        if (head.val == val) {
            head = head.next;
        }
        return head;
    }

      这个呢就是我们这个题的代码了,是不是很简单呢?Ok,理解这个题目之后,我们接着往下看下一道题。


❄️二、习题二:

☑ 题的链接:

        翻转链表的OJ链接

  思路:

在我们分析这个题的方法之前呢,我们先来看看其结果是什么: 

  那么我们这个操作是怎么做到的呢?我们来分析看看:

   我们的这个反转链表是不是相当于是头插呢?我们来看操作是不是定义一个节点用来存储 head 的下一个节点,这个节点就是要头插的节点当我们的 cur在 35 的时候,我们把 35 这个节点头插之后我们把 35 这个节点的 next 指向 head 这个节点,之后把 cur 这个节点设置为 head ,再继续 cur 往后走指向 45 这个节点,之后再进行头插并使 next 指向 head ,在设置head节点,重复这个操作,直至cur为空

    但是在这个操作中呢我们有几个要注意的点:

    1、我们在设置完cur之后呢,我们要把第一次的head节点置为 null ,因为当我们翻转之后呢原先的头会变成尾,所以要置null。

    2、我们在把cur节点头插之后呢,我们把cur的next指向head节点之后呢,我们就找不到原来cur的下一个节点了,所以我们要在头插之前就把cur的下一个节点存起来,防止丢失。

这样说呢,可能不够直观,我们来看看思路图,来更加直观的了解一下:

  ▶ 代码:

这个操作理解之后呢,我们来看看代码的实现: 

public ListNode reverseList(ListNode head) {
        //先判断链表是否为空
        if (head == null) {
            return head;
        }
        
        //开始头插
        ListNode cur = head.next;
        head.next = null; 
        while(cur != null) {
            //保存cur的下一个节点
            ListNode curNext = cur.next;
            cur.next = head;
            head = cur;
            cur = curNext;
        }
        return head;
    }

    OK,到这里呢,我们的第二题就已经结束了,让我们接着往下看下一题,这题是不是在理解之后就很简单了呢,如果不是很懂的话呢,也是可以画图理解一下。 


❄️三、习题三:

☑ 题的链接:

          链表的中间节点

    这个题用到的方法呢,是我们在做题的时候可能经常用到的方法:快慢指针法

  思路:

    这个题呢,它的返回的节点 和链表的长度也是有关的当我们的节点个数为奇数的时候返回的就是中间节点;当我们的节点个数为偶数的时候,返回的是第二个中间节点

     我们来看看图片理解一下:

   那么这个操作我们有时怎样做到的呢?快慢指针又是怎样使用的呢? 

     这里呢,我们要设置两个节点,一个为slow ,一个为fast,之后呢我们要对这两个节点进行移动,我们fast节点每次移动两步,而我们的slow每次走一步当我们的fast走到null的时候呢,我们slow这个节点就到达了中间节点

    但是呢我们要注意的是:我们的 fast 的结束条件是不一样的,当我们的节点数为奇数的时候,我们 fast 的 next 为空时就是结束条件但当我们的节点个数为偶数的时候呢,当 fast 为空的时候就是结束条件

这样的理解可能不是很直观啊,我们还是再来看看其执行的思路图和结束时fast在哪:

我们先来看看奇数的情况下: 

我们再来看看偶数的情况下: 

  ▶ 代码:

我们偶数和奇数的情况都已经分析完事了,让我们来看看代码是如何编写的:

public ListNode middleNode(ListNode head) {
        if (head == null) {
            return head;
        }
        ListNode fast = head;
        ListNode slow = head;
        
        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        
        return slow;
    }

      这里我们还要注意的是,我们的 while 的判断条件中,fast 和 fast.next 的判断的先后顺序是不能改变的,如果改变了的话,假如我们的 fast 为 null 了之后,我们先访问 fast.next 的话,就会出现空指针异常。

  我们又结束了一道题目,我们还要继续往下看,我们来看下一道题: 


❄️四、习题四:

☑ 题的链接:

            返回倒数第k个节点

         思路:

         这个题呢,我们用到的也是 快慢指针 的做法,但是呢这个题的快慢指针和上面的又是有所不同的,上面的快慢指针是fast 走2步,slow 走1步。这里呢,我们的做法呢,是先把 fast 走 k-1 步,之后再那 fast 和 slow一起走,直到 fast.next 为空的时候呢,slow 就是我们要返回的节点

         我们来看看思路图,来直观地了解一下:

        我们呢,这样看呢是不是发现我们 链表结尾和要返回的节点的距离 和 我们的一开始要设置的fast 和slow之间的距离是一样的。

     代码:

      那么接下来我们来看看我们的这个题的代码是怎样写的:

public int kthToLast(ListNode head, int k) {
        ListNode fast = head;
        ListNode slow = head;
        
        while(k - 1 > 0) {
            fast = fast.next;
            k--;
        }
        while(fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow.val;
    }

   到这我们的这道题也结束了,让我们接着看下一道题:


❄️五、习题五:

☑ 题的链接:

            合并两个有序链表

  思路:     

          对于这个题呢,我们呢要创建一个新的链表,因为这两个链表是有序地,所以呢我们呢可以对比两个链表的相对应位置的元素的大小,每次数值小的元素插入到新的链表当中,但是呢我们需要返回新链表的头结点,所以呢我们在插入之前呢我们需要先把新链表的位置保存下来,防止我们找不到头。但是我们要返回新链表的下一个节点,这才是我们的有效数据的节点。

  代码: 

我们来看看这个题的代码如何编写:

public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode newList = new ListNode();
        ListNode prev = newList;
        while(list1 != null && list2 != null) {
            if (list2.val <= list1.val) {
                prev.next = list2;
                list2 = list2.next;
            }else {
                prev.next = list1;
                list1 = list1.next;
            }
            prev = prev.next;
        }
        if (list1 != null) {
            prev.next = list1;
        }
        if (list2 != null) {
            prev.next = list2;
        }

        return newList.next;
    }

  OK啊,我们呢这个题也完事了,我们接下来继续往下看下一题: 


 ❄️六、习题六:

☑ 题的链接:

          链表的分割

     思路:

      这个题呢,在我们分析之前呢,我们先来看看这个题是什么意思: 

     这个题呢就是我们有一个 x 这个数值,当小于 x 的时候我们要把这个节点呢放到前面,而大于等于的呢放到后面,而且呢不能改变原来的数据顺序,我们来看表更直观的了解一下:

就是呢,这个意思。我们在来看看如何做这道题:

     我们这么分析,我们把小于 x 的 和 大于等于 x 的分成两个链表,一个呢放小于 x 的节点,另一个呢放大于等于 x 节点的数据 最后呢我们把小于 x 的链表的尾巴 和 大于 x 的链表的头连接在一起,再返回小于 x 链表的头。在返回之前呢我们要注意的是,我们的大于 x 的这个链表的尾巴节点不等于 null 的时候,我们要把其设置为null。我们来看看分析的思路图:

  代码:

OK,我们分析完如何做呢,我们呢来看看代码是怎样实现的:

public ListNode partition(ListNode pHead, int x) {
        // write code here
        ListNode smallHead = null;
        ListNode smallLast = null;
        ListNode bigHead = null;
        ListNode bigLast = null;
        ListNode cur = pHead;
        while (cur != null) {
            if (cur.val < x) {
                if (smallHead == null) {
                    //第一次删除的时候
                    smallHead = smallLast = cur;
                } else {
                    smallLast.next = cur;
                    smallLast = smallLast.next;
                }
            } else {
                if (bigHead == null) {
                    bigHead = bigLast = cur;
                } else {
                    bigLast.next = cur;
                    bigLast = bigLast.next;
                }
            }
            cur = cur.next;
        }
        if (smallHead == null) {
            return bigHead;
        }
        smallLast.next = bigHead;
        if (bigLast != null) {
            bigLast.next = null;
        }
        return smallHead;
    }
}

OK了,这个题呢我们也完事呢,我们继续往下看下一道题: 


❄️七、习题七:

 ☑ 题的链接:

            链表的回文结构

     ▶ 思路:     

     这个题,我们还是请到我们的老朋友  快慢指针——双指针法 在分析这个题之间呢,我们先来看一下什么是 回文结构 从前往后的结果和从后往前打印的结果是一样的,就是回文结构。比如我们来看这个图:

     这个呢就是 回文结构 从前往后是12->35->45->35->12 从后往前呢是 12->35->45->35->12 这就是回文结构了。 

      那么对于这个题呢,我们要怎样才能判断其链表是否是回文结构呢?我们呢对于这个题其实三步就可以了,第一:我们用双指针 fast 走2步 和 slow 走1步 来寻找中间节点,第二:再把中间节点后面的节点进行翻转,第三:在从头和从后面进行对比 val 值,每次都往前走一步进行对应位置的比较。我们来看看思路图是什么样的:

      是不是以为这样就结束了呢?当然不是了,我们在上面只是分析了奇数的情况下,但是呢我们没有分析偶数的情况下是什么样的。所以呢,我们再来看看偶数的情况下是什么样的:

  代码: 

这样呢就把奇数和偶数的情况都分析完事了,之后我们来看看代码如何编写:

public boolean chkPalindrome(ListNode head) {
        //双指针法:快慢指针法
        if (head == null ) {
            return true;
        }
        //找中间节点,slow就是中间节点。
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        //翻转中间节点后面的链表
        ListNode cur = slow.next;
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curNext;
        }

        //判断是否回文
        while (head != slow) {
            if (head.val != slow.val) {
                return false;
            }
            //这里需要判断一下偶数的情况下
            if (head.next == slow) {
                return true;
            }
            head = head.next;
            slow = slow.next;
        }
        return true;
    }

  这样呢,我们的这个回文结构的题呢,就结束了。 


❄️总结:

       OK啊,这次的对于链表的练习题就到这里就结束了,我们对于下次的分享呢,我们来分享关于栈的相关的知识了。希望这次的链表的习题对于你们有所帮助吧!!!让我们期待下次的见面吧,拜拜~~~

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

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

相关文章

包的相关知识

1. java定义了一种名字空间&#xff0c;称之为包&#xff1a;package。一个类总属于某个包&#xff0c;类名只是一个简写&#xff0c;真正的完整类名应该是”包名.类名“。 2. 在Java虚拟机执行的时候&#xff0c;JVM只看完整类名&#xff0c;只要包名不同&#xff0c;类就不同…

keysight346A安捷伦346B噪声源HP346B-18Ghz

keysight346A安捷伦346B噪声源HP346B-18Ghz Agilent 346B | HP-346B 噪声源|惠普|安捷伦|噪声头|HP-346B 品牌:美国安捷伦 Agilent | 美国惠普 HP Agilent 346B选件H01高ENR噪声源 Agilent 346B选件H01有高的ENR&#xff08;典型值为21dB &#xff09;适于测量噪声系数很大的…

【媒体邀约】论企业宣传与媒体合作

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 在探讨企业宣传与媒体合作的策略和实施时&#xff0c;可以从以下结构进行论述&#xff1a; 一、前言 企业宣传与媒体合作在当代商业环境中扮演着至关重要的角色。随着信息科技的发展和媒…

第二证券:有风险!筹码集中股出炉,这10股股东数骤降

深圳华强&#xff1a;存在商场心境过热的风险 昨日晚间&#xff0c;深圳华强发布《股票生意失常不坚定及严峻失常不坚定暨风险提示公告》。公司在公告中提示&#xff0c;近期公司股价短期涨幅较大&#xff0c;明显违背商场走势&#xff0c;存在商场心境过热的风险。但公司基本…

景区智慧公厕系统能给景区带来什么价值?

在当今数字化时代&#xff0c;景区智慧公厕系统正逐渐成为提升景区品质和游客体验的重要组成部分。 一、智慧公厕系统大屏功能 智慧公厕系统的大屏界面功能丰富多样。它可以实时显示公厕内的布局图&#xff0c;清晰地标明各个厕位的使用情况&#xff0c;让游客一目了然。同时&a…

【Google Play】Via浏览器5.8.1最新国际版(如何鉴别是否官方?)

via 浏览器&#xff0c;为您的安卓设备带来清爽无打扰的上网体验&#xff0c;不会推送新闻和其他内容&#xff0c;让您的设备保持纯净。体积小巧&#xff0c;内存占用极低&#xff0c;确保您的安卓设备如同新机般运行流畅。简约设计&#xff0c;是极简主义爱好者和技术达人的首…

查看vue项目的node版本

如果项目使用的 yarn 和 typescript&#xff0c;可以査看yarn.lock里的types/node 的 version: "types/node*" :"integrity" "sha1-ZhA9Ltxxxxxxxxxxxx""resolved" "https://registry.npm.taobao.xxxxxxxx""version&q…

Linux 磁盘管理-磁盘接口类型和分区看这一篇就够了

今天给伙伴们分享一下Linux 磁盘管理-磁盘接口类型和分区&#xff0c;希望看了有所收获。 我是公众号「想吃西红柿」「云原生运维实战派」作者&#xff0c;对云原生运维感兴趣&#xff0c;也保持时刻学习&#xff0c;后续会分享工作中用到的运维技术&#xff0c;在运维的路上得…

【机器学习】深度学习的现实应用——从图像识别到自然语言处理

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、深度学习的概述1.1 深度学习的定义1.1.1 什么是深度学习1.1.2 深度学习的历史与发展 1.2 深度学习与传统机器学习的区别1.2.1 特征工程的区别1.2.2 模型复杂度与计算能力的对比 1.3 深度学习的关键技术1.3.1 人工神经网…

xampp安装federated插件,实现mysql数据同步

需求&#xff1a;a服务器上的mysql数据库data表插入新数据时&#xff0c;需要同步到b服务器上的data表中。 解决&#xff1a;a服务器上开启federated引擎插件&#xff0c;创建data1对应b服务器上的data表。 在a服务器上的data表创建触发器&#xff0c;data表插入数据后执行触发…

【自动驾驶】控制算法(八)横向控制Ⅰ | 算法与流程

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

ASTER L2 表面反射率 SWIR 和 ASTER L2 表面反射率 VNIR V003

ASTER L2 Surface Reflectance SWIR and ASTER L2 Surface Reflectance VNIR V003 ASTER L2 表面反射率 SWIR 和 ASTER L2 表面反射率 VNIR V003 简介 ASTER 表面反射率 VNIR 和 SWIR (AST_07) 数据产品 (https://lpdaac.usgs.gov/documents/996/ASTER_Earthdata_Search_Ord…

Windows11系统本地部署Fooocus结合内网穿透远程AI生成图片

文章目录 前言1. 本地部署Fooocus图像生成软件1.1 安装方式1.2 功能介绍 2. 公网远程访问Fooocus3. 固定Fooocus公网地址 前言 本篇文章将介绍如何在本地Windows11电脑部署开源AI生图软件Fooocus&#xff0c;并结合Cpolar内网穿透工具轻松实现公网环境远程访问与使用。 Foooc…

在Windows系统上部署PPTist并实现远程访问

在Windows系统上部署PPTist并实现远程访问 前言PPTist简介本地部署PPTist步骤1&#xff1a;获取PPTist步骤2&#xff1a;安装依赖步骤3&#xff1a;运行PPTist 使用PPTist远程访问PPTist步骤1&#xff1a;安装Cpolar步骤2&#xff1a;配置公网地址步骤3&#xff1a;配置固定公网…

SAP NATIVE SQL

【应用场景】 1. 往对方中间库表中直接新增数据库表记录 2. 通过数据库中间件直接读取对方系统数据库表 【知识点】1. 连接数据库 2.读取数据 3.关闭数据库连接 4. 游标的使用 【前置条件】DB2配置对应对方系统的数据库连接是通的。有时因为密码过期或改了会导致数据库…

本地生活服务平台排名榜揭秘!如何通过搭建本地生活服务系统入局?

当前&#xff0c;本地生活赛道的热度不断攀升&#xff0c;想要通过本地生活服务商这一身份入局分羹的创业者数量更是不计其数。这让本地生活市场的竞争日渐激烈的同时&#xff0c;也让各类本地生活服务平台排行榜成为他们的重点关注对象。 而综合多个本地生活服务平台排行榜来看…

跟李沐学AI:语言模型

语言模型定义 假设在给定长度为T的文本序列中的词元依次为&#xff0c;可被人做文本序列在时间步t处的观测或标签。在给定这样的文本序列是&#xff0c;语言模型的目标是估计序列的联合概率。 一个理想的与语言模型能够在一次抽取一个词元的情况下基于模型本身生成自然文本。…

力扣343-整数拆分(Java详细题解)

题目链接&#xff1a;343. 整数拆分 - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 dp五部曲。 1.确定dp数组和i下标的含义。 2.确定递推公式。 3.dp初始化。 4.确定dp的遍历顺序。 5.如果没…

vue项目 / 资产管理

参考&#xff1a; https://blog.csdn.net/A_Common_Man/article/details/124601367 App.vue <template><div id"app"><div class container><h4 style"text-align: center; margin-top: 20px">资产管理</h4> <table …

【C语言进阶】C语言进阶教程:利用结构体、联合体和枚举自定义数据类型

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C语言 “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C语言内存管理函数 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C语言自定义类型 &#…