LeetCode环形链表

本文探讨了两种经典算法——哈希表法和Floyd判圈法,用于解决链表中是否存在环的问题。哈希表法通过查找节点出现次数快速定位环首,而Floyd的快慢指针则利用节点移动速度差异找到环的位置。两种方法都实现了O(1)空间复杂度的解决方案。
摘要由CSDN通过智能技术生成

题目 环形链表||

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

进阶:

你是否可以使用 O(1) 空间解决此题?
在这里插入图片描述

题解 哈希

哈希的话比较简单,建立一个set<ListNode*> 的哈希,遇见一个没有出现过的结点就插入,遇见的结点已经出现过说明这个节点就是环形的开始位置。
附完整代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head == NULL)
           return NULL;
        set<ListNode*> st;;
        while(head != NULL){
            if(st.find(head) == st.end())
                st.insert(head);
            else{
                return head;
            }
            head = head->next;
        }
        return NULL;
        
    }
};

题解 Floyd判圈法

实际上是快慢指针的应用!建立两个指针,一个fast,一个slow,fast一次走两步,slow一次走一步,那么fast走的路程是slow的两倍!
在这里插入图片描述如果存在环形,那么fast一定会在某个位置追上slow,如上图所示,设slow走的路程为S1,fast走的路成为S2,则S2 = 2 S1 并且 S2 - S1 = m *(b + c) = S1;就是说fast比slow多走了m圈的环形链表的长度,此时让slow回到原点,当slow到达了环形的入口处,那么行走的距离为a,则快指针走的路程为2S1 + a,其中S1为绕环走的m圈,总体来说,就是fast先到达入口处,然后溜达了2m圈与slow相遇!
附完整代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
      if(head == NULL || !head->next)
         return NULL;
      ListNode* fast = head;
      ListNode* slow = head;
    do{
          fast = fast->next->next;
          slow = slow->next;
      }while(fast && fast->next && slow != fast);
      if(slow == fast){
          slow = head;
          while(slow != fast){
              fast = fast->next;
              slow = slow->next;
          }
          return fast;
      }
      return NULL;        
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值