// 面试题23:链表中环的入口结点
// 题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中,
// 环的入口结点是结点3。

#include <iostream>
#include "List.h"ListNode* MeetingNode(ListNode* pHead)//鲁棒一:先确定有没有环,有的话先求得环中任意一个节点
{if (pHead == nullptr)//若头结点为空return nullptr;ListNode* pSlow = pHead->m_pNext;if (pSlow == nullptr)//若只有一个节点return nullptr;ListNode* pFast = pSlow->m_pNext;while (pFast != nullptr && pSlow != nullptr)//判断碰到尾节点后有没有环
    {if (pFast == pSlow)return pFast;pSlow = pSlow->m_pNext;pFast = pFast->m_pNext;if (pFast != nullptr)//判断碰到尾节点后有没有环pFast = pFast->m_pNext;}return nullptr;
}ListNode* EntryNodeOfLoop(ListNode* pHead)//开始计算入口节点,第一步先求环的个数,第二步通过两个前后指针计算入口节点
{ListNode* meetingNode = MeetingNode(pHead);if (meetingNode == nullptr)//如果存在环,得到一个环中节点return nullptr;// 得到环中结点的数目int nodesInLoop = 1;ListNode* pNode1 = meetingNode;while (pNode1->m_pNext != meetingNode){pNode1 = pNode1->m_pNext;++nodesInLoop;}// 先移动pNode1,次数为环中结点的数目pNode1 = pHead;for (int i = 0; i < nodesInLoop; ++i)pNode1 = pNode1->m_pNext;// 再移动pNode1和pNode2ListNode* pNode2 = pHead;while (pNode1 != pNode2)//二者只能相遇在入口处
    {pNode1 = pNode1->m_pNext;pNode2 = pNode2->m_pNext;}return pNode1;
}// ==================== Test Code ====================
void Test(const char* testName, ListNode* pHead, ListNode* entryNode)
{if (testName != nullptr)printf("%s begins: ", testName);if (EntryNodeOfLoop(pHead) == entryNode)printf("Passed.\n");elseprintf("FAILED.\n");
}// A list has a node, without a loop
void Test1()
{ListNode* pNode1 = CreateListNode(1);Test("Test1", pNode1, nullptr);DestroyList(pNode1);
}// A list has a node, with a loop
void Test2()
{ListNode* pNode1 = CreateListNode(1);ConnectListNodes(pNode1, pNode1);Test("Test2", pNode1, pNode1);delete pNode1;pNode1 = nullptr;
}// A list has multiple nodes, with a loop
void Test3()
{ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode4, pNode5);ConnectListNodes(pNode5, pNode3);Test("Test3", pNode1, pNode3);delete pNode1;pNode1 = nullptr;delete pNode2;pNode2 = nullptr;delete pNode3;pNode3 = nullptr;delete pNode4;pNode4 = nullptr;delete pNode5;pNode5 = nullptr;
}// A list has multiple nodes, with a loop
void Test4()
{ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode4, pNode5);ConnectListNodes(pNode5, pNode1);Test("Test4", pNode1, pNode1);delete pNode1;pNode1 = nullptr;delete pNode2;pNode2 = nullptr;delete pNode3;pNode3 = nullptr;delete pNode4;pNode4 = nullptr;delete pNode5;pNode5 = nullptr;
}// A list has multiple nodes, with a loop
void Test5()
{ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode4, pNode5);ConnectListNodes(pNode5, pNode5);Test("Test5", pNode1, pNode5);delete pNode1;pNode1 = nullptr;delete pNode2;pNode2 = nullptr;delete pNode3;pNode3 = nullptr;delete pNode4;pNode4 = nullptr;delete pNode5;pNode5 = nullptr;
}// A list has multiple nodes, without a loop
void Test6()
{ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode4, pNode5);Test("Test6", pNode1, nullptr);DestroyList(pNode1);
}// Empty list
void Test7()
{Test("Test7", nullptr, nullptr);
}int main(int argc, char* argv[])
{Test1();Test2();Test3();Test4();Test5();Test6();Test7();system("pause");return 0;
}

转载于:https://www.cnblogs.com/CJT-blog/p/10488977.html

《剑指offer》第二十三题(链表中环的入口结点)相关推荐

  1. 剑指offer(C++)-JZ23:链表中环的入口结点(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null. ...

  2. 剑指offer(C++)——链表中环的入口结点

    代码如下: struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} };/*思路:设 ...

  3. 《剑指Offer》23:链表中环的入口节点

    题目 若一个链表中包含环,如何找出的入口结点?如下图链表中,环的入口节点的节点3. 分析 一快(移两节点)一慢(移一节点)两指针判断链表是否存在环. 算出环有几个节点(上一步的两指针可知是在环中,让慢 ...

  4. 剑指offer-面试题23:链表中环的入口节点 快慢指针+双指针

    题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null.如图所示,节点3是链表中环的入口节点 本题的解决分为两步:(1)确定链表中是否有环(2)如果有环,确定环的入口节点. ...

  5. 剑指offer 附加1. 删除链表中的重复结点

    1.问题描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处 ...

  6. 剑指offer第二版答案详细版(带详细解题思路)

    1.滑动窗口的最大值(剑指offer原59题) 解题思路:其实是一个队列的问题,用一个队列去维护当前窗口中的所有元素:首先将超出窗口中的队头元素先删掉,然后将新的元素插入当前窗口中,插入时要判断新插入 ...

  7. 《剑指offer》刷题——【链表】从尾到头打印链表

    <剑指offer>刷题--[链表]-<从尾到头打印链表> 问题分析: 递归实现: 1. 无返回值 2. 有返回值(ArrayList) 问题分析: 从头到尾打印链表比较简单,那 ...

  8. 《剑指offer》-- 两个链表的第一个公共结点、链表中环的入口结点、删除链表中的重复结点

    一.两个链表的第一个公共结点: 1.题目: 输入两个链表,找出它们的第一个公共结点. 2.解题思路: (1)第一种:找出两个链表的长度,然后让长的链表先走两个链表的长度差,接着两个链表一起走. (2) ...

  9. 剑指Offer第二版Java代码实现

    剑指Offer第二版Java代码实现 A.单例模式 面试题 2:实现Singleton模式 B.面试需要的基础知识 面试题 3:数组中重复的数字 面试题 4:二维数组的查找 面试题 5:替换空格 面试 ...

  10. 《剑指offer》75题 C++详细题解

    目录 简单: 剑指 Offer 03. 数组中重复的数字 map: unordered_map: 原地交换 剑指 Offer 05. 替换空格 剑指 Offer 06. 从尾到头打印链表 出栈入栈 双 ...

最新文章

  1. flash绘图API:绘制植物
  2. 6款强大的jQuery插件 创建和加强网站布局
  3. 表贴3.3V稳压芯片 PL3500测试 低压差线性稳压器
  4. [导入]Update实现多表更新
  5. 关于HTML下overflow-y:auto无效、清除HTML默认边距、解决去除手机访问网页时的左右多余空白的三个方法汇总
  6. c#随机数生成编号_使用C#生成随机密码(纯数字或字母)和随机卡号(数字与字母组合)...
  7. 挤牙膏机器,实话,没啥用
  8. dbcontext mysql_mysql – ‘DbContextOptionsBuilder’不包含’UseSqlServer’的定义
  9. 数据结构那些事(二)
  10. react实现全选和反选_全选的实现
  11. Java案例:生成指定目录下某种类型文件的列表
  12. 实现两边定宽,中间自适应布局(三栏布局)的七种方法
  13. 带有SeekBar的Android Media Player歌曲
  14. java是解释执行么
  15. 【华为HCIE安全考什么科目?华为HCIE安全考什么知识点?】
  16. 读书有感:《失业的程序员》
  17. 我喜欢的图片不是png格式怎么办,使用Windows电脑1分钟搞定格式转换
  18. java caller_callee和caller属性的区别
  19. 【Python学习笔记】6:用Gauss-Legendre求积公式近似求积分值
  20. Django入门到放弃 学习笔记 03

热门文章

  1. Open3D+vs配置以及使用教程
  2. 2021-06-28操作表单
  3. 用access建立一个试题库_我想建立一个试题库,用Access可吗?还 – 手机爱问
  4. java redis源码分析,慢谈 Redis 实现分布式锁 以及 Redisson 源码解析
  5. vba commondialog控件添加不上_MyVBA加载宏——添加自定义菜单03——功能分析
  6. 表锁 行锁 页锁 是什么区别
  7. html th width无效 解决方法
  8. java 实体类重写排序,对自定义对象进行排序(C++/Java) | 学步园
  9. php之mvc设计模式的原理和实现
  10. php基础之常量(系统常量,自定义常量)