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

链表拆分与快慢指针相关算法题

一拆分为二

C = a 1 , b 1 , a 2 , b 2 , … , a m , b m C={a_{1},b_{1},a_{2},b_{2},\dots,a_{m},b_{m}} C=a1,b1,a2,b2,,am,bm,为线性表,采用带头节点的单链表存放,将其拆分为两个线性表
使得 A = a 1 , a 2 , … , a n A=a_{1},a_{2},\dots,a_{n} A=a1,a2,,an B = b n , … , b 2 , b 1 B=b_{n},\dots,b_{2},b_{1} B=bn,,b2,b1

算法思想

循环遍历链表C,
采用尾插法将一个节点插入表A,这个节点为奇数号节点,这样建立的表A与原来的节点顺序相同;
采用头插法将下一节点插入表B,这个节点为偶数号节点,这样建立的表B与原来的节点顺序正好相反
![[Pasted image 20241106204401.png]]

malloc一个B头节点,将B的next指向NULL
![[Pasted image 20241106204918.png]]

用一个工作指针cur来指向A表的第一个节点,准备遍历A表
用一个tail指针指向A头节点,用来尾插找尾
cur往后遍历A表,直到cur指向空时结束
![[Pasted image 20241106205224.png]]

将tail的next也就是A的next指向cur,这里不动
![[Pasted image 20241106205257.png]]

tail指针后移,指向A表的最后一个节点
![[Pasted image 20241106205326.png]]

cur指向cur的next,后移一位
这时候cur走向偶数位置,判断cur是否指向空
用next保存cur的下一个节点
![[Pasted image 20241106205457.png]]

cur的next指向B的next,将cur头插到B表
![[Pasted image 20241106205601.png]]

B的next指向cur
![[Pasted image 20241106205626.png]]

cur指向next
![[Pasted image 20241106205647.png]]

再进行A表的尾插
![[Pasted image 20241106205815.png]]

再进行B表的头插
![[Pasted image 20241106205842.png]]

将tail的next指向NULL
![[Pasted image 20241106210017.png]]

LinkList DisCreat(LinkList &A)
{LinkList B = (LinkList)malloc(sizeof(LNode));  //创建B表表头B->next = NULL;     //B表初始化LNode* cur = A->next, *next;  //cur为工作指针LNode* tail = A;         //tail始终指向A的尾节点while (cur){tail->next = cur;    //将*cur链到A的表尾tail = cur;cur = cur->next;if (cur){next = cur->next;  //头插后,*cur将断链,用next记忆*cur的后继cur->next = B->next;  //将*cur插入到B表的前端B->next = cur;cur = next;}}tail->next = NULL;    //A尾节点的next指向NULLreturn B;
}

判断链表是否带环

单链表有环,是指单链表的最后一个节点的指针指向了链表中的某个节点,判断单链表是否存在环

算法思想

设置快慢指针分别为fast和slow最初都指向链表头head
slow每次走一步,fast每次走两步
fast走得比slow快,若有环,则fast一定先进入环
两个指针进入环后,一定会在环上相遇
链表分割|链表的回文结构|相交链表|环形链表|随机链表的复制©-CSDN博客
这里有详细说明过程,环形链表1和2
![[Pasted image 20241106221440.png]]

LNode* FindLoopStart(LNode* head)
{LNode* fast = head, *slow = head;  //设置两个快慢指针while (fast && fast->next){slow = slow->next;             //每次走一步fast = fast->next->next;       //每次走两步if (slow == fast)              //相遇break;}if (fast == NULL || fast->next == NULL)return NULL;                   //没有环,返回空LNode* p1 = head, *p2 = slow;      //分别指向开始点,相遇点while (p1 != p2){p1 = p1->next;p2 = p2->next;}return p1;                         //返回入口点
}

一个指针从头节点开始走,一个节点从相遇点开始走,当两个指针相遇的时候,就是入口点

返回倒数第k个节点

输入一个链表,输出该链表的倒数第k个节点

算法思想

快慢指针思想
将fast指针指向链表的第k+1个节点,slow指向链表的第一个节点,此时fast和slow之间刚好相差k个节点,两个指针同步向后走,当fast走到链表的尾部空节点时,slow指针正好指向链表的倒数第k个节点
![[Pasted image 20241106225844.png]]

fast先走k步,之后同步走
![[Pasted image 20241106225922.png]]

直到fast指向空
![[Pasted image 20241106230012.png]]

LNode* getKthFromEnd(LinkList &head, int k)
{if (head == NULL)return NULL;LNode* fast = head, *slow = head;int i = 0;while (fast){if (i >= k){slow = slow->next;}fast = fast->next;i++;}return slow;
}

http://www.mrgr.cn/news/67278.html

相关文章:

  • Elasticsearch Interval 查询:为什么它们是真正的位置查询,以及如何从 Span 转换
  • Uniswap:去中心化交易所的创新与原理
  • Rust 构建 TCP/UDP 网络服务
  • 如何处理vue项目中的错误
  • 工作中问题
  • 【美洽看 AI】客户服务未来已来,AI Agent 如何改变游戏规则?
  • Go语言基础语法
  • WebGUI之Gradio:Gradio 5的简介、安装和使用方法、案例应用之详细攻略
  • Cerebellum:浏览器 AI 助手,基于 Claude 3.5 Sonnet 和 Selenium WebDriver 执行网页自动化任务
  • 二进制流文件下载和预览
  • SpringBoot3集成Junit5
  • C++ 多态
  • 写歌词的技巧和方法:以情动人,打造感人歌词,妙笔生词AI智能写歌词软件
  • Jest项目实战(2): 项目开发与测试
  • 详解:字符串常量池
  • Linux入门之vim
  • Git超详细笔记包含IDEA整合操作
  • 狐假虎威,数据流图其实很简单
  • 题目练习之二叉树那些事儿
  • Centos7修改默认yum源(ARM架构)(2024年6月30号后)
  • 防火墙|WAF|漏洞|网络安全
  • 信息学奥赛一本通 1395:烦人的幻灯片(slides)
  • Flutter鸿蒙next 中的 Drawer 导航栏
  • 【360】基于springboot的志愿服务管理系统
  • 粒子群优化双向深度学习!PSO-BiTCN-BiGRU-Attention多输入单输出回归预测
  • 【云岚到家】-day09-2-秒杀抢购