《剑指offer》第二十三题(链表中环的入口结点)
- // 面试题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 = ;
- ListNode* pNode1 = meetingNode;
- while (pNode1->m_pNext != meetingNode)
- {
- pNode1 = pNode1->m_pNext;
- ++nodesInLoop;
- }
- // 先移动pNode1,次数为环中结点的数目
- pNode1 = pHead;
- for (int i = ; i < nodesInLoop; ++i)
- pNode1 = pNode1->m_pNext;
- // 再移动pNode1和pNode2
- ListNode* 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");
- else
- printf("FAILED.\n");
- }
- // A list has a node, without a loop
- void Test1()
- {
- ListNode* pNode1 = CreateListNode();
- Test("Test1", pNode1, nullptr);
- DestroyList(pNode1);
- }
- // A list has a node, with a loop
- void Test2()
- {
- ListNode* pNode1 = CreateListNode();
- ConnectListNodes(pNode1, pNode1);
- Test("Test2", pNode1, pNode1);
- delete pNode1;
- pNode1 = nullptr;
- }
- // A list has multiple nodes, with a loop
- void Test3()
- {
- ListNode* pNode1 = CreateListNode();
- ListNode* pNode2 = CreateListNode();
- ListNode* pNode3 = CreateListNode();
- ListNode* pNode4 = CreateListNode();
- ListNode* pNode5 = CreateListNode();
- 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();
- ListNode* pNode2 = CreateListNode();
- ListNode* pNode3 = CreateListNode();
- ListNode* pNode4 = CreateListNode();
- ListNode* pNode5 = CreateListNode();
- 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();
- ListNode* pNode2 = CreateListNode();
- ListNode* pNode3 = CreateListNode();
- ListNode* pNode4 = CreateListNode();
- ListNode* pNode5 = CreateListNode();
- 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();
- ListNode* pNode2 = CreateListNode();
- ListNode* pNode3 = CreateListNode();
- ListNode* pNode4 = CreateListNode();
- ListNode* pNode5 = CreateListNode();
- 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 ;
- }
《剑指offer》第二十三题(链表中环的入口结点)的更多相关文章
- 【剑指Offer】55、链表中环的入口结点
题目描述: 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 解题思路: 本题是一个比较典型的链表题目,难度适中.首先,对于大多人来说,看到这道题是比较开心的 ...
- 剑指offer(55)链表中环的入口节点
题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 题目分析 1.一快一慢指针,先找到碰撞点. 2.然后碰撞点到入口节点的距离就是头结点到入口节点的距离. 具体原理可 ...
- 【Offer】[23] 【链表中环的入口结点】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 一个链表中包含环,如何找出环的入口结点?  思路分析 判断链表中是否有环:用快慢指针的方法,慢指针走一步,快指针走两步,如果快指针追上 ...
- 剑指offer 56.删除有序链表中的重复结点
56. 删除有序链表中的重复结点 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3-> ...
- 【Java】 剑指offer(23) 链表中环的入口结点
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中, ...
- 链表中环的入口结点 牛客网 剑指Offer
链表中环的入口结点 牛客网 剑指Offer 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. # class ListNode: # def __init__(se ...
- 【剑指Offer】链表中环的入口结点 解题报告(Python)
[剑指Offer]链表中环的入口结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...
- 剑指offer第二章
剑指offer第二章 1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含 ...
- 剑指offer:从头到尾打印链表
目录 题目 解题思路 具体代码 题目 题目链接 剑指offer:从头到尾打印链表 题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 解题思路 首先题目实际给出的要求是返回ve ...
随机推荐
- linux lvs
- bzoj3196: Tyvj 1730 二逼平衡树 树套树
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3196 题目: 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec ...
- cf 459E
cf459E 这题说的是 给定一个n点m条边的带边权的有向图,从中找出一条路径(可以带环),该路径包含的边数最多,并且要求路径中的权值必须严格递增,然后对边进行排序完个后采用dp去解特殊判断一下边权值 ...
- jq 自定义标注小组件 $.widget
html 部分 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...
- Azkaban-开源任务调度程序(安装篇)
最近项目迁移到新集群,试试同事推荐的开源任务调度程序-azkaban(阿兹卡班),没看错,就是哈利波特里的阿兹卡班,azikaban主要用来解决hadoop依赖任务的执行,但是它本身支持linux和j ...
- python在交互模式下直接输入对象后回车,调用的是对象的__repr__()方法,这个方法表示的是一个编码,用print+对象是调用对象的__str__方法
交互模式下调用对象的__repr__()方法,这个方法表示的是一个编码 >>> u"国庆节快乐"u'\u56fd\u5e86\u8282\u5feb\u4e50' ...
- 20145101《Java程序设计》第6周学习总结
20145101<Java程序设计>第6周学习总结 教材学习内容总结 第十章输入和输出 java.io.InputStream.java.io.OutputStream实例分别作为输入.输 ...
- SPI、CAN、I2C
SPI是串行外设接口(Serial Peripheral Interface)的缩写.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局 ...
- IntelliJ IDEA 连接数据库 详细过程
IntelliJ IDEA集成了众多插件,方便开发者使用,使用其自带的Database模块就可以很方便的配置.连接到数据库,本次操作以MySQL为例,其中testjdbc数据库已经提前建好,里面有两张 ...
- 怎样用QtCreator编辑运行python脚本
QtCreator作为一款开发基于qt库的程序.以及开发C语言.c++语言项目都是一个利器,轻便好用.那么作为开发者来说,经常换着使用各种IDE是家常便饭,但是要是这些语言都能够集成到一个工具里岂不是 ...