链表每日一练

获取链表的中间节点 简单

思路一

寻找中间节点:先遍历链表获得链表的长度,然后除以2得到的整数下标就是中间节点的位置。

代码实现

java 复制代码
public static int MiddleList(ListNode root){
    //root为空没有中间节点返回 -1
    if (root == null){
        return -1;
    }
    //获取链表长度
    ListNode cur = root.head;
    int size = 0;
    while(cur != null){
        cur = cur.next;
        size++;
    }
    //获取中间节点
    cur = root.head;
    for (int i = 0; i < size/2; i++){
        cur = cur.next;
    }
    return cur.val;
}

思路二

设计两个指针从头结点开始,让快指针走的速度是慢指针的两倍,当快指针走到null时,慢指针就在中间节点位置。

java 复制代码
public static int MiddleList(ListNode root){
    //root为空没有中间节点返回 -1
    if (root == null){
        return -1;
    }
    ListNode slow = root.head;
    ListNode fast = root.head;
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow.val;       
}

思路二通过快慢指针,找到中间节点的时间消耗更少。

反转单链表

思路

因为单链表在反转过程中会无法再次获得下一个节点,因此需要三个标记来,一个记录下一个节点的位置,两个负责反转任务

java 复制代码
lass Solution {
    public ListNode reverseList(ListNode head) {
        ListNode slow = head;//慢节点
        ListNode fast = head;//快节点
        ListNode cur = head;//cur保存原fast下一个节点
        //如果链表为空不进入反转
        //头结点需要进行单独反转
        if(fast != null){
        //先将cur放在头结点反转后的位置
            cur = cur.next;
            if(cur != null){
                cur = cur.next;
            }
            //进去头结点反转
            fast = fast.next;
            //如果链表只有一个节点直接返回
            if(fast == null){
                return head;
            }
            fast.next = slow;
            slow.next = null;//将反转后的链表最后一个节点需要为null
            slow = fast;
        }
        //反转整个链表
        while(cur != null){
            fast = cur;
            cur = cur.next;
            fast.next = slow;
            slow = fast;
        }
        //反转后链表的头为fast
        head = fast;
        return head;
    }
}

链表倒数第 k 个节点

思路

让快标记在慢标记前 k 个节点,遍历两个标记,当快标记为null时,慢标记在倒数 k 个节点

java 复制代码
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        //防止链表为空或者倒数节点为负数
        if(head == null || k < 1){
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        for(int i = 0; i<k ;i++){
        //当k大于链表长度时fast会走到空
            if(fast == null){
                return null;
            }
            fast = fast.next;
        }
        while(fast != null){
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}

总结

本文介绍了链表操作中的三个经典问题及其解决方案:

  1. 获取链表的中间节点:提供了两种思路

    • 思路一:先遍历链表获取长度,再遍历到中间位置
    • 思路二:使用快慢指针,快指针速度是慢指针的两倍,当快指针到达末尾时,慢指针正好在中间位置
  2. 单向链表反转:使用三个指针配合完成反转操作

    • 两个指针负责反转节点间的连接
    • 一个指针记录下一个需要处理的节点位置
    • 需要注意头节点的特殊处理
  3. 链表中倒数第k个节点:使用快慢指针技巧

    • 快指针先走k步
    • 然后快慢指针同步前进
    • 当快指针到达末尾时,慢指针正好在倒数第k个位置

算法技巧总结:

  • 快慢指针是解决链表问题的常用技巧,可以用于寻找中间节点、倒数第k个节点等
  • 多指针配合在链表反转等操作中非常有效
  • 边界条件处理很重要,如空链表、k值过大等情况都需要考虑

这些算法不仅是面试中的常见题目,也是理解链表数据结构操作的基础。掌握这些技巧可以帮助你更好地解决更复杂的链表问题。

相关推荐
蜗牛互联网8 分钟前
Python Agent 工具调用:审批令牌、参数白名单和累计预算
java·开发语言·人工智能·windows·后端·python
哦虎!10 分钟前
【JavaEE】网络编程套接字
java
Wang's Blog12 分钟前
Java 项目实战: 交友项目 - SpringCloud 整合 Dubbo 的方案概述
java·spring cloud·交友
Logic10113 分钟前
C语言/数据结构组合数学题解:数字好排列计数——质数倍数分类与阶乘取模
c语言·数据结构·算法·组合数学·时间复杂度·排列·取模运算
imDwAaY29 分钟前
程序里的地址是真实内存地址吗?从虚拟内存到地址转换
java·linux·服务器
承渊政道40 分钟前
【Python编程—从入门到实践】(让程序记得、恢复并解释失败:Python 文件、异常与JSON系统教程)
开发语言·python·pycharm·json·异常处理
秋饼44 分钟前
Claude Haiku 5.5 + Spring AI 2.0 企业级低成本高并发 AI Agent 实战:子智能体分工、成本熔断与百万上下文落地
java·ai·技术分享·后端开发
一水鉴天1 小时前
声调韵的序:从古汉语音韵到系统科学语言的场效应推演 20261013(千问)
开发语言·人工智能
郭庆汝1 小时前
(六)MCP+A2A之——Playwright与BrowserUse:让AI学会像人类一样使用浏览器
开发语言·python
longlongzihan1 小时前
LeetCode 25. K 个一组翻转链表 (迭代+分组反转法)
算法·leetcode·链表