56 - 链表中环的入口节点

题目:

一个链表中包含环,如何找出环的入口节点? 例如 1->2->3->4->5->6->(3) ; 的链表中,环的入口及诶到哪是节点 3。



解析:

  • 首先找到链表中的环:定义2个指针,一个快指针一次走2步,一个慢指针一次走1步,如果2个指针能够相遇,证明有环。
  • 统计链表中环的长度:从相遇指针开始,固定 1 个指针,另一个指针从相遇指针走,当2个指针再次相遇时,即走了 1 圈,得到环的长度 len。
  • 2个指针指向链表开头,1个指针先走 len 步,另一个指针从头和前一个指针一起走,当 2 个指针相遇时,即是环的入口。
#include <iostream>
using namespace std;
class Node {
public:
    int val;
    Node* next;
    Node(int v, Node* n = NULL):val(v), next(n) {};
};
int GetCircleNodeNums(Node* pHead) {
    if (pHead == NULL)
        return 0;
    // 一快一慢,相遇时,则找到环
    Node* pSlow = pHead;
    Node* pFast = pSlow->next;
    while (pFast != NULL && pSlow != NULL) {
        if (pFast == pSlow)
            break;
        pSlow = pSlow->next;
        if (pFast->next) {
            pFast = pFast->next->next;
        } else {
            break;
        }
    }
    // 固定一个指针,一个指针走,再次相遇时,则是一圈,得到环长度
    int counts = 0;  // 如果 p1, p2 有一个为NULL,则不存在环,返回0
    Node* p1 = pFast, *p2 = pSlow;
    if (p1 == p2 && p1 != NULL) {
        p1 = p1->next;
        counts++;
        while (p1 != p2) {
            p1 = p1->next;
            counts++;
        }
    }
    return counts;
}

Node* FindCircleEntrance(Node* pHead) {
    if (pHead == NULL)
        return NULL;
    int circle_len = GetCircleNodeNums(pHead);
    if (circle_len == 0)
        return NULL; // 没有环
    Node* p1 = pHead, *p2 = pHead;
    // p1 先走一个环的长度
    while (circle_len) {
        p1 = p1->next;
        circle_len--;
    }
    // p1, p2 一起走,相遇时则是环的入口
    while (p1 != p2) {
        p1 = p1->next;
        p2 = p2->next;
    }
    return p1;
}

int main() {
    // 1->2->3->4->5->6->(3)
    Node* pList = NULL;
    Node* pNode1 = new Node(1, NULL);
    Node* pNode2 = new Node(2, NULL);
    Node* pNode3 = new Node(3, NULL);
    Node* pNode4 = new Node(4, NULL);
    Node* pNode5 = new Node(5, NULL);
    Node* pNode6 = new Node(6, NULL);
    pNode1->next = pNode2;
    pNode2->next = pNode3;
    pNode3->next = pNode4;
    pNode4->next = pNode5;
    pNode5->next = pNode6;
    pNode6->next = pNode3;
    pList = pNode1;

    cout << "环的长度 :"<< GetCircleNodeNums(pList) << endl;
    Node* EntranceNode = FindCircleEntrance(pList);
    if (EntranceNode)
        cout << "环的入口节点的值:"<< EntranceNode->val << endl;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-18 08:38:31

56 - 链表中环的入口节点的相关文章

C++实现查找链表中环的入口节点

/* * 寻找链表中环的入口节点.cpp * * Created on: 2018年4月10日 * Author: soyo */ #include<iostream> using namespace std; struct Node{ int num; Node * next; }; Node * creat() { Node *head; Node *p; head=new Node; p=head; p->num=10; p->next=NULL; return head;

剑指offer(二十三,二十四,二十五)最小的k个数,连续子数组的最大和,链表中环的入口节点

23:最小的k个数 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 简单题.... function GetLeastNumbers_Solution(input, k) { if(k>input.length) return []; let ans = []; input = input.sort(); //console.log(input.join("").slice(0,4).split

剑指Offer对答如流系列 - 链表中环的入口节点

面试题23:链表中环的入口节点 问题描述 一个链表中包含环,如何找出环的入口结点?例如,在图中的链表中,环的入口结点是结点3. 链表的结构 public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } 问题分析 首先不能忽略链表中不包含环的情况,第一件事情必须先确定链表是否有环:我们可以使用两个引用,一个跑的快.一个跑的慢,同时出发,跑的快的追上跑的慢的自然说明有环.(

剑指offer:链表中环的入口节点

题目描述给一个链表,若其中包含环,请找出该链表的环的入口节点,否则,输出null. # -*- coding: utf-8 -*- # @Time : 2019-04-23 22:40 # @Author : Jayce Wong # @ProjectName : job # @FileName : entryNodeOfLoop.py # @Blog : https://blog.51cto.com/jayce1111 # @Github : https://github.com/SysuJa

链表--链表中环的入口节点

此题设快慢两个指针,先判断是否有环:如果为环快慢指针终会相遇: 找入口节点:快慢指针相遇的节点到入口节点的距离,与从头节点开始新的慢指针到相遇点的距离相同. 可画图演示.因为快指针是慢指针的两倍速,且他们在q点相遇,则我们可以得到等式 2(A+B) = A+B+C+B.得出C=A function EntryNodeOfLoop(pHead){ if(pHead == null || pHead.next == null||pHead.next.next==null){ return null;

链表中环的入口节点

题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 分析一:用HashSet解决 1 public class Solution { 2 public ListNode EntryNodeOfLoop(ListNode pHead) 3 { 4 if(pHead==null){return null;} 5 HashSet<ListNode> set=new HashSet<ListNode>(); 6 while(pHead!=null){ 7 if

链表中环的入口结点-剑指Offer

链表中环的入口结点 题目描述 一个链表中包含环,请找出该链表的环的入口结点. 思路 若该链表存在环,设置两个指针pSlow和pFast,pSlow每次走一步,pFast每次走两步,当pFast追上pSlow的时候,pFast比pSlow多走的正好是pSlow走的也就是环所包含的节点的个数. 所以,第二次走,一个从头结点开始,另一个从相遇节点开始,最终会在环的入口节点相遇 代码 /* public class ListNode { int val; ListNode next = null; Li

【单链表】找出单链表中环的“入口”

题目: 找出单链表中环的"入口". 解答步骤: 1.用快慢指针判断是否存在环(慢指针走一步,快指针走两步).若存在环则继续下面的计算,若不存在则返回nullptr: 2.记录快慢指针相遇的节点n0. 3.一个指针从链表头结点出发,另一个指针从n0出发,"同步前进",相遇的节点就是环的"入口". 分析: 由于快慢指针所走的"步数"相同,但快指针每一步是慢指针的两倍,所以快慢指针在n0相遇时,快指针所走距离是慢指针的两倍,即: S

剑指offer 55. 链表中环的入口结点

55. 链表中环的入口结点 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null 法一:(我没看懂) 思路:https://blog.nowcoder.net/n/76e8af2d2fad49f990cde6e6b60a4d79?f=comment 快慢指针,快指针一次走两步,慢指针一次走一步,相遇后,快指针回到头结点,以一次一步的速度和慢指针一起走,再次相遇的结点即是环的入口点 1 public class Solution { 2 3 public ListNo