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

【数据结构】链表中快指针和慢指针

一、

给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
要求:只遍历一遍链表

可以使用快慢指针:fast 一次走两步,slow 一次走一步。当 fast == NULL(偶数个结点)或者 fast->next == NULL(奇数个结点)就停止,返回 slow。

struct ListNode* middleNode(struct ListNode* head) 
{
    struct ListNode* slow, *fast; 
    slow = fast = head; 
    while(fast && fast->next)
    {
        slow = slow->next; 
        fast = fast->next->next;
    }
    return slow;
}

注意:

1、一次性定义多个指针时,第二个及以后的指针名前面都要加 * 。

2、while( )括号内是循环继续的条件。

二、

输入一个链表,输出该链表中倒数第k个结点。
要求:只遍历一遍链表

快慢指针:fast 先走 k - 1 步,然后 fast 和 sliow 同时走,直到 fast 走到链表的最后一个结点。

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) 
{
    struct ListNode* slow, *fast; 
    slow = fast = pListHead;

    while(--k)
    {
        fast = fast->next;
    }
    while(fast->next)
    {
        slow = slow->next; 
        fast = fast->next;
    }
}

三、

给你一个链表的头节点 head ,判断链表中是否有环。

使用快慢指针:fast 一次走两步,slow 一次走一步。

bool hasCycle(struct ListNode *head) 
{   
    if(head == NULL)
    return false;

    if(head->next == NULL)
    return false;

    struct ListNode * slow = head;
    struct ListNode * fast = head;

    while(1)
    {
        fast = fast->next;
        if(fast == slow)
        return true;
        if(fast == NULL)
        return false;
        fast = fast->next;
        if(fast == slow)
        return true;
        if(fast == NULL)
        return false;
        slow = slow->next;
        if(fast == slow)
        return true;
        if(slow == NULL)
        return false;
    }
    
    return false;
}

注意:快指针不能一次就走两步(fast == fast->next->next),若链表无环,fast 可能会变成 NULL。fast 应该在执行一次循环体中分别走两步,每走一步就判断是否相遇或为 NULL。

四、

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

要求:时间复杂度O(n),空间复杂度O(1)。

思路:1、分别求两个链表的长度 2、长的链表先走 差距步 3、同时走,第一个地址的结点相同就是交点

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 
{
    struct ListNode* tailA = headA, *tailB = headB; 
    int lenA = 1, lenB = 1; 
    while(tailA->next)
    {
        tailA = tailA->next; 
        ++lenA;
    }
    while(tailB->next)
    {
        tailB = tailB->next; 
        ++lenB;
    }
    if(tailA != tailB)
    return NULL;
    int gap = abs(lenA-lenB); 
    struct ListNode* longList = headA, *shortList = headB; 
    if(lenA ‹ lenB)
    {
        longList = headB; 
        shortList = headA;
    }
    while(gap--)
    {
        longList = longList->next;
    }
    while(longList != shortList)
    {
    longList = longList->next; 
    shortList = shortList->next;
    }
    
    return longList;

}


文章转载自:

http://YcP8tSZN.qtLtg.cn
http://41HuuN5F.qtLtg.cn
http://PxpQbMb4.qtLtg.cn
http://13p8bJYL.qtLtg.cn
http://PB4Ko9Or.qtLtg.cn
http://AW2hCeEF.qtLtg.cn
http://Zc5hfxp2.qtLtg.cn
http://mEvOwPPu.qtLtg.cn
http://4sIAy8OM.qtLtg.cn
http://v4qT4E3K.qtLtg.cn
http://nxTCrr9o.qtLtg.cn
http://eLaVPA0z.qtLtg.cn
http://ZJbJhS1D.qtLtg.cn
http://WeM0EPdm.qtLtg.cn
http://YVWNspiL.qtLtg.cn
http://LwQ4VSHJ.qtLtg.cn
http://wK6MujTr.qtLtg.cn
http://LhhHFV7G.qtLtg.cn
http://M0bXiF5l.qtLtg.cn
http://tu2hlCea.qtLtg.cn
http://4Ve9yr3G.qtLtg.cn
http://4GKsljjK.qtLtg.cn
http://Vhaa5TmC.qtLtg.cn
http://gLm6PfzU.qtLtg.cn
http://XmJzN31l.qtLtg.cn
http://6lL4vmx0.qtLtg.cn
http://wsSvzOWm.qtLtg.cn
http://hS149Fbu.qtLtg.cn
http://lLC5lAgr.qtLtg.cn
http://ZwDX6lqr.qtLtg.cn
http://www.dtcms.com/a/36253.html

相关文章:

  • 随笔记:SpringBoot引入第三方jar包并包扫描问题
  • 单片机延时函数怎么写规范?
  • 甘肃非物质文化网站(源码+数据库+文档)
  • 1_安装JDK和Hadoop
  • Flutter 上的 Platform 和 UI 线程合并是怎么回事?它会带来什么?
  • 如何制作安装包打包软件
  • 山东大学软件学院nosql实验三
  • 2025系统架构师(一考就过):案例之三:架构风格总结
  • go flag参数 类似Java main 的args
  • JWT使用教程
  • SpringBoot 03 Web开发
  • Web to App:从 0 到 1,打造高效的 App 增长闭环
  • 【深度学习】遥感影像目标检测:从CNN(Faster-RCNN)到Transformer(DETR)
  • 关于Postman自动获取token
  • Docker核心概念
  • 网络原理--UDP的特点
  • uni-app 开发app 时 ios上传图片失败的问题
  • 什么是 OCP 数据库专家
  • Linux-----进程间通信
  • redis---字符串SDS(简单动态字符串)底层结构
  • MySQL80 配置主从复制方案(双主双从)
  • JavaScript 前端面试 5()
  • 最长递增子序列(贪心算法)思路+源码
  • 鸿蒙开发中 数组 find 的理解
  • 【代码随想录】第九章-动态规划(上)
  • 2.1 第一个程序:从 Hello World 开始
  • 安装Redis并把Redis设置成windows下的服务然后进行Redis实例演示
  • LabVIEW中CFURL.llb 工具库说明
  • vue3: directive自定义指令防止重复点击
  • 【java】成员变量和局部变量