《剑指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 ...
随机推荐
- Java接口多线程并发测试 (一)
本文为作者原创,禁止转载,违者必究法律责任!!! 本文为作者原创,禁止转载,违者必究法律责任!!! Java接口多线程并发测试 一,首先写一个接口post 请求代码: import org.apach ...
- Java中将xml文件转化为json的两种方式
原文地址https://blog.csdn.net/a532672728/article/details/76312475 最近有个需求,要将xml转json之后存储在redis中,找来找去发现整体来 ...
- ARM中的汇编指令
Arm指令,32位的指令集,一共有16条的基本指令,每条指令都可以按条件执行, 指令都是32bit的,高四位是条件码[31:28], Thumb指令,16位的指令集,执行效率比arm指令集要低,但是节 ...
- meta 如何写
阻止手机号加下划线,可拨打:<meta name="format-detection" content="telephone=no" /> (io ...
- swift 之 as、as!、as?
1,as使用场合(1)从派生类转换为基类,向上转型(upcasts) class Animal {} class Cat: Animal {} let cat = Cat() let animal = ...
- Impala和Hive的关系(详解)
Impala和Hive的关系 Impala是基于Hive的大数据实时分析查询引擎,直接使用Hive的元数据库Metadata,意味着impala元数据都存储在Hive的metastore中.并且im ...
- Python: 合并多个字典
现在有多个字典或者映射,想将它们从逻辑上合并为一个单一的映射后执行某些操作,比如查找值或者检查某些键是否存在. eg1: a = {'x': 1, 'z': 3 }b = {'y': 2, 'z': ...
- python 用正则表达式把”0102030405”分成5组('0', '1'), ('0', '2'), ('0', '3'), ('0', '4'), ('0', '5')
把”0102030405”分成5组('0', '1'), ('0', '2'), ('0', '3'), ('0', '4'), ('0', '5') re.findall(r"(\d)(\ ...
- 完美解决Linux服务器tomcat开机自启动问题
经过多次测试终于彻底解决tomcat开机自启动的问题了 PID3=`ps aux | grep /home/server/shichuan/ | grep java | awk '{print $2} ...
- web前端----Bootstrap框架补充
一.一个小知识点 1.截取长屏的操作 2.设置默认格式 3.md,sm, xs 4.空格和没有空格的选择器 二.响应式介绍 - 响应式布局是什么? 同一个网页在不同的终端上呈现不同的布局等- 响应式怎 ...