首页 > 其他分享 >环形链表II

环形链表II

时间:2024-05-29 22:35:27浏览次数:25  
标签:II head slow ListNode 结点 环形 fast 链表 哈希

前两天一直在debug,今天才有时间好好刷一下力扣,今天在代码随想录上看到环形链表,链接如下:https://leetcode.cn/problems/linked-list-cycle-ii/description/

这道题官方有两种解法,一种是相对比较简单的哈希表,还有一种是利用数学计算出他们的规律进而解题。
首先说第二种,在示例中

      3 -> 2 -> 0-> 4->
	   ^            |
	   <- <- <-  <-

链表从3开始,依次对2 0 4 2 0 4进行遍历。如果无环返回null,有环的话求他们的环起始点。本质上这是两个问题,所以先对第一个问题求解:判断是否有环。在这里我们先设置两个指针,也就是双指针法(fast/low),然后我们fast指针每次遍历两个结点,low指针每次遍历一个结点,那么最后他们一定在环中相遇。

而后计算他们在入环中的第一个入环结点,这个我是直接看的答案,想了一会一点思路没有果断放弃 :-<(妈的看答案还得反应半天)
简单来说:设从起始结点到环起始点的距离为x,环起始点到他们在环中相遇的结点距离是y,相遇的点要走z个结点回到环起始点,具体的图如下:
image
那么从这图中和我们之前设置可知,slow指针共走了x+y个结点,fast指针共走了x+y+n(y+z)个结点。由于fast和slow是二倍的关系,所以可以列等式

(x + y) * 2 = x + y + n ( y + z ) 
 x = (n - 1)(x + y) + z

n是fast在相遇前走过的圈数。然后进行化简得到第二行,这里n是需要大于等于1的,因为fast指针必须至少转1圈,否则就出现没转一圈直接和slow相遇了(这不符合常理!)综上,当n = 1时,x = z。也就是一个结点从相遇的点开始出发,另一个点从头结点开始出发,走相同的距离然后相遇。起始n不等于1也是一样,只是在环中的结点要多走几圈罢了。代码实现如下:


class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if((head == nullptr) || (head->next == nullptr)){
            return nullptr;
        }
        struct ListNode* slow = head;
        struct ListNode* fast = head;
        do{
            int count = 0;
            while((count != 2)&&(fast != NULL)){
                fast = fast->next;
                count++;
            }
            slow = slow->next;
        }
        while((fast != slow)&&(slow != nullptr));
        struct ListNode* q = fast;
        struct ListNode* p = head;
        while((p!=NULL)&&(q!=NULL)){
            if(p == q){
                return p;                
            }
            p = p->next;
            q = q->next;
        }
        return nullptr;
    }
};

代码写的过于冗余,但是还是可以看懂的。
同时还有一种方法是哈希表,虽然数据结构学过哈希表,但是并没有在C++中用过,所以写的不太熟练。
如果用哈希表的话那么就会简单很多了,下面是详细解释官方题解(因为没怎么用过)


class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        // 定义一个哈希表用于存储访问过的节点
        unordered_set<ListNode *> visited;
        
        // 遍历链表
        while (head != nullptr) {
            // 如果当前节点已经在哈希表中,说明遇到了环
            if (visited.count(head)) {
                return head; // 返回环的起点
            }
            // 将当前节点加入哈希表
            visited.insert(head);
            // 移动到下一个节点
            head = head->next;
        }
        
        // 如果没有遇到环,返回 nullptr
        return nullptr;
    }
};

unordered_set<ListNode > visited;
//无序集合来存链表中的结点指针,集合中每个元素都是ListNode
的指针
然后需要遍历链表,每个结点在哈希表中貌似都是head结点

if (visited.count(head)) {     //使用visited.count(head)检查当前结点是否在集合中,
    return head;		//如果返回1就代表访问过了,就代表我们遇到环了,
}			       //当前结点就是环起点。

visited.insert(head); 当前结点没访问过的话,就把此结点添加到集合中,同时移动到下个结点head = head->next;

标签:II,head,slow,ListNode,结点,环形,fast,链表,哈希
From: https://www.cnblogs.com/ink-bai/p/18221253

相关文章

  • Day 8 | 344.反转字符串 、541. 反转字符串II 、151.翻转字符串里的单词
    344.反转字符串建议:本题是字符串基础题目,就是考察reverse函数的实现,同时也明确一下平时刷题什么时候用库函数,什么时候不用库函数题目链接/文章讲解/视频讲解:https://programmercarl.com/0344.反转字符串.html思考太简单了classSolution:defreverseString(self,......
  • UCOS-II的基本概念
    原文链接:https://blog.csdn.net/mjy520123/article/details/120297177UCOS—II一、实时操作系统的概念1.1操作系统​操作系统是一种系统软件,他在计算机硬件与计算机应用程序之间,通过提供程序接口,屏蔽了计算机硬件工作的一些细节,从提高了应用程序的开发效率。​应用在嵌入式系......
  • 59天【代码随想录算法训练营34期】第十章 单调栈part02( ● 503.下一个更大元素II ●
    503.下一个更大元素IIclassSolution:defnextGreaterElements(self,nums:List[int])->List[int]:dp=[-1]*len(nums)stack=[]foriinrange(len(nums)*2):while(len(stack)!=0andnums[i%len(nums)]>nums[stack[-1......
  • 封装通用 ECharts 图表组件(三):环形图实现
    在数据可视化领域,ECharts是一个非常流行且功能强大的图表库。它提供了丰富的图表类型,能够满足各种复杂的数据展示需求。在本系列的第三篇文章中,我们将探讨如何封装一个通用的ECharts环形图组件。什么是环形图?环形图是一种特殊的饼图,它由一个内圆和一个外圆组成,中间的部分是......
  • leetCode.82. 删除排序链表中的重复元素 II
    leetCode.82.删除排序链表中的重复元素II题目思路:代码classSolution{public:ListNode*deleteDuplicates(ListNode*head){autodummy=newListNode(-1);dummy->next=head;autop=dummy;while(p->next){......
  • 探索数据结构:单链表的实践和应用
    ......
  • 2-链表-41-两两交换链表中的节点-LeetCode24
    2-链表-41-两两交换链表中的节点-LeetCode24参考:代码随想录LeetCode:题目序号24更多内容欢迎关注我(持续更新中,欢迎Star✨)Github:CodeZeng1998/Java-Developer-Work-Note技术公众号:CodeZeng1998(纯纯技术文)生活公众号:好锅(Lifeismorethancode)CSDN:CodeZeng1998......
  • 数据结构-单向链表的实现(c语言)
    链表的定义:链表是由一系列的结点组成的,每个结点包含两个域,分别是指针域(*next)与数据域(data)。单向链表的实现//.h文件#ifndeDXLB_H#defineDXLB_H//定义结点结构体typedefstructLINKNODE{structLINKNODE*next;//指向下一个结点的指针intdata;......
  • 反转链表
    leetcode:206.需求:反转链表原链表:graphLRA-->B-->C-->D-->null反转后:graphRLD-->C-->B-->A-->null graphLR D-->C-->B-->A-->null双指针法:/***Definitionforsingly-linkedlist.*publicclassListNode{*......
  • iic发送地址后没有应答
    现象描述iic主机发送地址后,从机没有返回信号给主机,即没有应答信号。分析首先是硬件有没有问题,包括传感器虚焊、地址选择口有没有添加这些。先检查硬件是否连接正常,保证能有信号给到从机。再者,软件的问题,包括iic控制是否正常、传感器地址是否正确、速率匹配问题、是否符合iic协......