zoukankan      html  css  js  c++  java
  • LeetCode142:Linked List Cycle II

    题目:

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

    Follow up:
    Can you solve it without using extra space?

    解题思路:

    判断链表有无环,可用快慢指针进行,快指针每次走两步,慢指针每次走一步,如果快指针追上了慢指针,则存在环,否则,快指针走到链表末尾即为NULL是也没追上,则无环。

    为什么快慢指针可以判断有无环?

    因为快指针先进入环,在慢指针进入之后,如果把慢指针看作在前面,快指针在后面每次循环都向慢指针靠近1,所以一定会相遇,而不会出现快指针直接跳过慢指针的情况。

    如何找到环的入口点呢?

    我们先看图再说话:

    image

    从图各段我们分析,因为quick指针每次走两步二slow指针每次走一步,所以当两指针相遇时,quick走了两倍的slow指针所走长度即:假设相遇点为z点

    a + b + n * ( b + c ) = 2 * (a + b)  公式1

    整理得:

    a = n * (b + c) – b  公式2

    根据公式2可知,要找到环入口点,可使用两个指针,p1和p2,p1从链表头开始走,p2从z点即快慢指针相遇点开始走,当p1指针走到Y(环入口点)时即长度为a时,p1走了n * (b + c) – b,可知p1也正好在Y点,所以利用p1和p2两指针,当它们相遇时,相遇点即为环入口点。

    实现代码:

    #include <iostream>
    using namespace std;
    
    /**
    Linked List Cycle II
     */
     
    struct ListNode {
         int val;
         ListNode *next;
         ListNode(int x) : val(x), next(NULL) {}
    };
    void addNode(ListNode* &head, int val)
    {
        ListNode *node = new ListNode(val);
        if(head == NULL)
        {
            head = node;
        }
        else
        {
            node->next = head;
            head = node;
        }
    }
    void printList(ListNode *head)
    {
        while(head)
        {
            cout<<head->val<<" ";
            head = head->next;
        }
    }
    
    class Solution {
    public:
        ListNode *detectCycle(ListNode *head) {
            if(head == NULL || head->next == NULL)
                return NULL;
            ListNode *quick = head;
            ListNode *slow = head;
            while(quick && quick->next)//利用快慢指针判断有无环 
            {
                quick = quick->next->next;
                slow = slow->next;
                if(quick == slow)
                    break;
            }
            if(quick != slow)
                return NULL;
            //slow指针从头开始走,quick指针从相遇点开始走,根据公式可知,相遇点即为环入口点 
            slow = head;
            while(slow != quick)
            {
                slow = slow->next;
                quick = quick->next;
            }
            return slow;                
        }
    };
    int main(void)
    {
        ListNode *head = new ListNode(1);
        ListNode *node1 = new ListNode(2);
        ListNode *node2 = new ListNode(3);
        ListNode *node3 = new ListNode(4);
        head->next = node1;
        node1->next = node2;
        node2->next = node3;
        node3->next = node1;
        
        Solution solution;
        ListNode *rNode = solution.detectCycle(head);
        if(rNode)
            cout<<rNode->val<<endl;
        
        return 0;
    }
  • 相关阅读:
    POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】
    HDU 5687 Problem C 【字典树删除】
    HDU 1298 T9【字典树增加||查询】
    AIM Tech Round 5 (rated, Div. 1 + Div. 2) C. Rectangles 【矩阵交集】
    基本数据结构:栈-队列-双向队列
    Elasticsearch 环境准备
    django项目部署
    linux基础
    购物车
    Python内置函数
  • 原文地址:https://www.cnblogs.com/mickole/p/3671467.html
Copyright © 2011-2022 走看看