当前位置: 首页 > news >正文

环形链表相关题目

876 链表的中间节点

题目描述

思路 :快慢指针

快指针 fast 每轮走两步,慢指针每轮走一步,因此当快指针遍历完链表时,慢指针就指向链表中间节点。

链表长度为奇数: 当 fast 走到链表「尾节点」时,slow 正好走到「中间节点」。

链表长度为偶数: 当 fast 走到「null」时(越过「尾节点」后),slow 正好走到「第二个中间节点」。

总结以上规律,应在当 fast 遇到或越过尾节点 时跳出循环,并返回 slow 即可。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode slow=head;
        ListNode fast=head;
        while(fast!=null && fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        return slow;
    }
}

若题目要求返回「第一个中间节点」,则应在 fast 遇到尾节点或其前驱节点 时跳出循环。此时,修改判断条件为 while fast.next and fast.next.next 即可。

141. 环形链表

题目描述

思路

如果链表有环,快慢指针,快指针走2步慢指针走1步,肯定能够碰见;

如果没有环,那么会退出while循环

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
 /**
 使用快慢指针
  */
public class Solution {
    public boolean hasCycle(ListNode head) {
       if(head == null || head.next==null) return false;
       ListNode slow=head;
       ListNode fast=head.next;
       while(fast!=null && fast.next!=null){
           if(slow==fast) return true;
           slow=slow.next;
           fast=fast.next.next;
       }
       return false;        
    }
}

142. 环形链表 II

题目描述

思路

快慢指针

快慢指针图解

我们先判断是否有环,然后再判断环的入口

假设从头结点到环形入口节点 的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点 节点数为y。 从相遇节点 再到环形入口节点节点数为 z。 如图所示:

相遇的时候,慢指针走的距离是 x+y,快指针走的距离是 x+y+n(y+z)

如果我们让快指针每次移动两步,慢指针移动一步,那么快指针走过的距离就是慢指针的 2 倍

所以 2(x+y)=x+y+n(y+z)

n(y+z)=x+y

x=(n-1)(y+z)+z

我们会发现:从相遇点到入环点的距离加上 n−1 圈的环长,恰好等于从链表头部到入环点的距离。

因此,当发现 slow 与 fast 相遇时,我们再额外使用一个指针 ptr。起始,它指向链表头部;随后,它和 slow 每次向后移动一个位置。最终,它们会在入环点相遇。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {// 有环
                ListNode index1 = fast;
                ListNode index2 = head;
                // 两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口
                while (index1 != index2) {
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }
        return null;
    }
}

哈希表

我们遍历链表中的每个节点,并将它记录下来;一旦遇到了此前遍历过的节点,就可以判定链表中存在环。借助哈希表可以很方便地实现。

public class Solution {
    public ListNode detectCycle(ListNode head) {
        //可以利用set的去重特性来解决
        //set的add方法,如果元素添加成功则返回true
        if(head==null || head.next==null) return null;
        Set<ListNode> set=new HashSet();
        ListNode p=head;
        while(p!=null){
            //只要set添加元素不成功,则说明这个结点之前已经添加过了
            //这个结点就是重复的结点
            if(set.contains(p){
                return p;
            }else{
                p=p.next;
            }
            
        }
        //说明链表不是循环链表
        return null;
    }
}
public class Solution {
    public ListNode detectCycle(ListNode head) {
        //可以利用set的去重特性来解决
        //set的add方法,如果元素添加成功则返回true
        if(head==null || head.next==null) return null;
        Set<ListNode> set=new HashSet();
        while(head!=null){
            //只要set添加元素不成功,则说明这个结点之前已经添加过了
            //这个结点就是重复的结点
            if(!set.add(head)){
                return head;
            }else{
                head=head.next;
            }
            
        }
        //说明链表不是循环链表
        return null;
    }
}
http://www.dtcms.com/a/110023.html

相关文章:

  • ARM架构安装MySQL8.0
  • 数据结构每日一题day11(链表)★★★★★
  • Python HTTP交互双剑客:requests与responses实战指南
  • 2025年消防设施操作员考试题库及答案
  • 矩池云使用指南
  • 高级IO模型
  • 华三H3C模拟器HCL搭建简单内网三层网络
  • Lua:第1-4部分 语言基础
  • Compose组件转换XML布局
  • 煤矿沿线 智能输入输出模块,一般用来干什么
  • 使用 Vue3 打造一个简易分类器演示工具
  • LLM大模型教程——为什么要学习AI大模型
  • 力扣HOT100之矩阵:240. 搜索二维矩阵 II
  • DLL修复工具4DDiG.DLL.Fixer
  • 雷达图 之 缺失值忽略
  • PMP考试改革解读:新题型+5A通关秘籍
  • 基础科学中的人工智能︱如何用机器学习方法求解排列型组合优化问题?
  • SQL语句的训练
  • 如何在 Linux 上安装和配置 Zsh
  • 19728 拼十字
  • 算力重构营销生态:广电数字人 “造星“ 运动背后的智能革命
  • Ceph异地数据同步之-RBD异地同步复制(下)
  • NO.63十六届蓝桥杯备战|基础算法-⼆分答案|木材加工|砍树|跳石头(C++)
  • ZCC8702,LED驱动芯片的“六边形战士”可替代SY8707
  • 服务器有2张显卡,在别的虚拟环境部署运行了Xinference,然后又建个虚拟环境再部署一个可以吗?
  • ngx_time_init
  • EIR管理中IMEI和IMSI信息的作用
  • 【AI赋能:58招聘数据的深度剖析之旅】
  • NHANES指标推荐:BRI
  • 基于大模型的主动脉瓣病变预测及治疗方案研究报告