Day01 环形链表

60 阅读2分钟

141.环形链表

题目链接

题目描述

​ 给一个链表的头节点head,判断链表中是否有环

思路

​ 快慢指针,创建两个指针变量fast、slow,fast每次移动两个位置,slow每次移动一个位置,如果链表中有环存在,那么fast指针一定会在将在某个时间与slow相遇在同一节点。

代码实现
/*
 * struct ListNode{
 *		int val;
 *		ListNode *next;
 *		ListNode(int x) : val(x), next(NULL){}
 *};
 */
class Solution{
public:
    bool hasCycle(ListNode *head){
        //创建快慢指针
        ListNode *fast = head;
        ListNode *slow = head;
        //移动两个指针,如果没有相遇返回false
        while(fast && fast->next){
            fast = fast->next->next;
            slow = slow->next;
            // 相遇返回true
            if(fast == slow){
                return true;
            }
        }
        return false;
    }
};

142. 环形链表Ⅱ

题目链接

题目描述

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

思路
  • 创建快慢指针, 判断有环无环
  • 假如有环,快慢指针相遇,slow走了 x 距离, fast 走了 2x 距离,多出来的 x 的距离为 fast 在环内转圈的长度。
  • 设头节点到入环位置的长度为 n, 入环位置距slow指针位置长度为 x-n
  • 从fast最终位置再走x- (x-n) 步,也一定能到达入口位置。
  • 设置两个指针,分别从head结点和相遇点出发,走过n步会相遇,当两个指针相遇的时候,即为环的入口位置 ,返回此时节点。
  • 无环则返回NULL
代码
/*struct ListNode{
 *	int val;
 *	ListNode *next;
 *	ListNode(int x) : val(x), next(NULL){}
 *};
 */
class Solution{
  public:
    ListNode *detectCycle(ListNode *head){
        ListNode *fast = head;
        ListNode *slow = head;
        ListNode *index1 = head;
        ListNode *index2 = NULL;
        while(fast && fast->next){
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow){
                index2 = fast;
                break;
            }
        }  
        // 如果index2不为空,两个指针同步前进,相交即返回
        // 为空直接返回
        while(index2){
            if(index1 == index2){
                break;
            }
            index1 = index1->next;
            index2 = index2->next;
        }
        return index2;
    }
};