【数据结构(四)】链表经典练习题

这篇具有很好参考价值的文章主要介绍了【数据结构(四)】链表经典练习题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

❣博主主页: 33的博客❣
▶️文章专栏分类:数据结构◀️
🚚我的代码仓库: 33的代码仓库🚚
🫵🫵🫵关注我带你学更多数据结构知识

【数据结构(四)】链表经典练习题,数据结构,数据结构,链表,windows,循环链表,中间节点,回文链表

1.前言

在上一篇文章中博主已经介绍了链表的基础知识,什么是链表,如何实现一个链表,以及LinkedList的操作方法,那么在这篇文章中通过一些链表的经典习题来练习吧。

2.删除值为key的所有结点

删除值为val的所有结点:OJ链接
解题思路:

1.遍历链表。
2.如果某个结点A的值等于key,那么A的前一个结点B的next值直接等于A的next。
3,继续遍历,遇到等于值等于key的重复上诉操作,直到全部遍历完成。

public void removeAllKey(int key) {
    if (head==null){
        return;
    }
    Node node=head;
    Node cur=head.next;
    while (cur!=null){
        if(cur.val==key){
            node.next=cur.next;
            cur=cur.next;
        }else {
            node=node.next;
            cur=cur.next;
        }
    }
    if(head.val==key){
        head=head.next;
    }
    }

3.反转链表

反转链表:OJ链接

public ListNode reverseList(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        ListNode cur=head.next;
        head.next=null;
        while (cur!=null){
            ListNode curNext=cur.next;
            cur.next=head;
            head=cur;
            cur=curNext;
        }
        return head;
    }

4.返回中间结点

返回中间结点:OJ链接
方式一:
解题思路:

1.求链表的大小size
2.中间结点为size/2
遍历链表,走到size/2的位置,返回该节点

class Solution {
	//求链表长度
    public int size(ListNode head) {
        ListNode node=head;
        int count=0;
        while (node!=null){
           count++;
            node=node.next;
        }
        return count;
    }
    public ListNode middleNode(ListNode  head) {
        if(head==null||head.next==null){
            return head;
        }
        int Size=size(head);
        int middle=Size/2;
        ListNode node=head;
        for (int i=0;i<middle;i++){
            node=node.next;
        }
        return node;
    }    
}

方式二:
解题思路:

1.设置一个快结点:fast,设置一个慢结点:slow。
2.我们试想:如果fast的速度是slow的两倍,那么当fast到达路程的终点时,此时slow就走了路程的一半。
3.所以我们让fast每次走两步,slow每次走一步,当fast=null或者fast.next=null的时候,slow就是中间结点

public Node middleNode2() {
        Node fast=head;
        Node slow=head;
        while (fast!=null||fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }

5.输出倒数第k个结点

输入一个链表,输出该链表中倒数第k个结点:OJ链接
解题思路:

1。让fast先走k-1步数
2.再同时走,当fast到达终点时,那么它们就相差k
3.此时的slow就是倒数第k个结点

ublic Node FindKthToTail (int k) {
        Node fast=head;
        Node slow=head;
    if(k<=0||head==null){
        return null;
    }
    while (k-1>0){
        fast=fast.next;
        k--;
    }
    while (fast.next!=null){
        fast=fast.next;
        slow=slow.next;
    }
    return slow;
    }

6.链表分割

以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前:OJ链接
解题思路:

1.首先,遍历链表
2.再创建两个链表,一个用于存放小于x的值,另一个用于存放大于x的值
3.再把第一个链表的最后一个结点与第二个链表的头节点串起来。

public Node partition(int x) {
        if (head==null){
            return null;
        }
        Node as=null;
        Node ae=null;
        Node bs=null;
        Node be=null;
        Node cur=head;
        while (cur!=null){
            if (cur.val<x){
              if(as==null){
                  //插入第一个节点
                  as=cur;
                  ae=cur;
                  cur=cur.next;
              } else {
                  ae.next=cur;
                  ae=ae.next;
                  cur=cur.next;
              }
            }else {
             //cur.val>x
             if(bs==null){
             //插入第一个节点
                 bs=cur;
                 be=cur;
                 cur=cur.next;
             }  else {
                 be.next=cur;
                 be=be.next;
                 cur=cur.next;
             }
            }
        }
        //如果第一个链表为空就直接返回第二个链表的头节点
        if(as==null){
            return bs;
        }
        ae.next=bs;
        if(bs != null) {
            //第2个区间有数据
            be.next = null;
        }
        head=as;
        return head;
    }

7.链表回文

给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构:OJ链接
解题思路:

1.查看链表是否回文,是指从前向后遍历,或者从后向前遍历,输出的之都相同。
2.我们可以先找到中间位置,再从中间位置进行翻转,使它同时从两头向中间遍历
3.遍历的时候如果如果链表有偶数个的情况,和有奇数个的情况是不一样的,当有奇数个时,走到相同的位置就停止,当有偶数个时,当下再走一步就相遇时就停止。

public boolean chkPalindrome() {
		 if(head == null || head.next == null) {
            return true;
        }
        //按照中间位置翻转链表
        //1.找到中间位置(middle已经在4中写过)
        Node middle=middleNode2();
        //2.翻转
        Node ehead=middle;
        Node cur=ehead.next;
        while (cur!=null){
            Node curNext=cur.next;
            cur.next=ehead;
            ehead=cur;
            cur=curNext;
        }
        //从两头开始遍历
        Node snode=head;
        Node enode=ehead;
        while (snode!=enode){
            if (snode.val!=enode.val){
                return false;
            }
            if (snode.next==enode){
                return true;
            }
                snode=snode.next;
                enode=enode.next;
        }
        return true;
    }

8.相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点:OJ链接
解题思路:

1.求两个链表的长度,再求长度差值
2.定义节点fast代表长的链表头节点,slow代表短的链表的头节点。先让长的链表先走差值步,再同时走。
3.两个链表相遇时就是相交节点。

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {        
        ListNode nodeA=headA;
        ListNode nodeB=headB;
        int lenA=size(headA);
        int lenB=size(headB);
        ListNode fast=headA;
        ListNode slow=headB;
        int len=lenA-lenB;
        if(len<0){
            len=lenB-lenA;
            fast=headB;
            slow=headA;
        }
        while(len>0){
            fast=fast.next;
            len--;
        }
        while(fast!=slow&&fast!=null){
            fast=fast.next;
            slow=slow.next;
        }       
        return fast;      
    }

9.环形链表

9.1是否为环形链表

给你一个链表的头节点 head ,判断链表中是否有环:OJ链接
解题思路:

1.定义节点fast代表长的链表头节点,slow代表短的链表的头节点.
2.每次让fast走两步,slow走一步,如果是环形链表,那么它们一定会在环中的某一个位置相遇,否则不是环形链表
为什么每次让fast走两步,slow走一步?不可以fast走3步,4步吗?假设环中只有两个元素A,B,当slow进入环时在A的节点的位置,此时fast在B节点的位置,slow走一步就到B的位置,fast走3步就到A的位置,那么它们永远都不会相遇。
只有每次让fast走两步,slow走一步,换的长度为1,那么肯定会相遇。

 public boolean hasCycle(ListNode head) {
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            //fast.next!=null&&fast!=null,不能这样写
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
                return true;
            }   
        }
        return false;       
    }

9.2入环第一个节点

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null:OJ链接
解题思路:

让一个指针从链表起始位置开始遍历链表,同时让一个指针从判环时相遇点的位置开始绕环运行,两个指针都是每次均走一步,最终肯定会在入口点的位置相遇。
证明如下:

【数据结构(四)】链表经典练习题,数据结构,数据结构,链表,windows,循环链表,中间节点,回文链表

public class Solution {
    ListNode hasCycle(ListNode head) {
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            //fast.next!=null&&fast!=null,不能这样写
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
                return fast;
            }   
        }
        return null;       
    }
    public ListNode detectCycle(ListNode head) {
          ListNode fast=hasCycle(head);
          if(fast==null){
            return null;
          }
          ListNode slow=head;
          while(fast!=slow){
            fast=fast.next;
            slow=slow.next;
          }
          return fast;  
    }
}

10.总结

本篇博客主要对链表的经典习题进行了讲解,同学们要理解解题的一些思想做到融会贯通,如果有疑惑的地方欢迎大家来和博主沟通,交流。

下期预告:栈文章来源地址https://www.toymoban.com/news/detail-855233.html

到了这里,关于【数据结构(四)】链表经典练习题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】“单链表”的练习题(二)

    💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃 个人主页 :阿然成长日记 👈点击可跳转 📆 个人专栏: 🔹数据结构与算法🔹C语言进阶 🚩 不能则学,不知则问,耻于问人,决无长进 🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍 前言: 最近在刷题的

    2024年02月13日
    浏览(34)
  • 【数据结构】“单链表”的练习题(一)

    💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃 个人主页 :阿然成长日记 👈点击可跳转 📆 个人专栏: 🔹数据结构与算法🔹C语言进阶 🚩 不能则学,不知则问,耻于问人,决无长进 🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍 题目要求: 给你单链

    2024年02月12日
    浏览(33)
  • 力扣(LeetCode)数据结构练习题(2)

    今天又写了两道关于链表的练习题,来给大家分享一下。巩固一下上一篇学到的链表知识,题目可以然我们更清楚的认识链表。 目录 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表 给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中

    2024年02月21日
    浏览(39)
  • 数据结构与算法系列之习题练习

    💗 💗 博客:小怡同学 💗 💗 个人简介:编程小萌新 💗 💗 如果博客对大家有用的话,请点赞关注再收藏 🌞 括号匹配问题。 用队列实现栈。 用栈实现队列。 设计循环队列。 有效的括号 //用栈来实现 //左括号进栈 右括号出栈并销毁如果不匹配则return //设置两个队列,入栈

    2024年02月11日
    浏览(27)
  • 数据结构与算法--图(概念+练习题+解析)

    有向图 在有向图中有以下几点结论: 1.所有顶点的度数之和等于边数的二倍。 2.所有顶点的入度之和等于出度之和。 3.n个顶点的有向完全图有n(n-1)条边。 4.n个顶点的强连通图至少有n条边。 无向图 在无向图中有以下几点结论: 1.所有顶点的度数之和等于边数的二倍。 2.n个顶

    2024年02月04日
    浏览(27)
  • 【数据结构】时间复杂度---OJ练习题

    目录 🌴时间复杂度练习 📌面试题---消失的数字 题目描述 题目链接:面试题 17.04. 消失的数字 🌴解题思路 📌思路1: malloc函数用法  📌思路2: 📌思路3: 🙊 如果有不了解时间复杂度的请移步上一篇文章:【数据结构】初识 题目描述 数组 nums 包含从 0 到 n 的所有整数,

    2024年02月16日
    浏览(26)
  • 【数据结构】顺序表详解(附leetcode练习题)

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C语言和数据结构 🌼博客专栏:数据结构 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺

    2023年04月27日
    浏览(37)
  • 【数据结构】算法的时间复杂度和空间复杂度(下)(附leetcode练习题)

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C语言和数据结构 🌼博客专栏:数据结构 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 空间复杂度也是一个数学表达式,是对一个算法在运行过程中 临时占用的额外的存储空间大小的量度 。 空间复杂度不是程序占用

    2023年04月19日
    浏览(71)
  • 【数据结构】 算法的时间复杂度和空间复杂度 (上)(附leetcode练习题)

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C语言和数据结构 🌼博客专栏:数据结构 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 如何衡量一个算法的好坏呢?比如对于以下斐波那契数列: 斐波那契数列的递归实现方式非常简洁,但简洁一定好吗?那该如何

    2023年04月14日
    浏览(21)
  • 【数据结构】算法的时间复杂度和空间复杂度 (上)(附leetcode练习题)

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C语言和数据结构 🌼博客专栏:数据结构 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 如何衡量一个算法的好坏呢?比如对于以下斐波那契数列: 斐波那契数列的递归实现方式非常简洁,但简洁一定好吗?那该如何

    2023年04月22日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包