zoukankan      html  css  js  c++  java
  • 链表判断是否有环,如有,找入环节点

    一条链表如何判断是否有环?若是有环那怎么找到链表环的入口?

    解决思路

    • 先判断是否有环

    思路: 用快慢两个指针分别从链表头开始,慢指针一次走一个节点,快指针一次走两个节点next -> next,这样如果有环那快指针务必会跑到慢指针后面,随即两者之间的距离一次会缩小一步,最终相遇。若是未相遇且快指针的 next 为 null,则说明链表无环。

    • 若是有环怎么找到环入口

      如果快慢指针相遇,说明有环,假设起点到入环节点的距离为L,入环节点到相遇节点的距离为x,环的周长为L,根据速度可推出下面关系见

     假设n=1,也就是当快指针再走第二圈的时候和慢指针相遇,他们的关系为L=H - x

    也就是说,如果这个时候有一个指针temp从起点开始走,慢指针low 从相遇的地方开始走,当temp指针与low相遇的位置就是入环节点

    struct ListNode {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(nullptr) {}
    };
    // 快慢指针
    class Solution {
    public:
        bool hasCycle(ListNode *head) {
            //空链表或只有一个节点的链表不算环
            if (head == NULL || head->next == NULL)  
                return false;
            ListNode *fast = head->next;
            ListNode *slow = head;
            while (fast != slow) {
                if (fast->next == NULL || fast->next->next == NULL)
                    return false;
                fast = fast->next->next;
                slow = slow->next;
            }
            return true;
        }
    };
    //哈希表
    class Solution {
    public:
        bool hasCycle(ListNode *head) {
            unordered_map<ListNode*, int>mp;
    
            while (head != NULL) {
                mp[head]++;
                if (mp[head] > 1)
                    return true;
                head = head->next;
            }
            return false;
        }
    };

    判断是否有环+寻找入环节点

    class Solution {
    public:
        ListNode *detectCycle(ListNode *head) {
            ListNode *slow = head, *fast = head, *p = head;
            while(fast && fast->next)
            {
                slow = slow->next;
                fast = fast->next->next;
                if(slow == fast)            //如果链表存在环
                {
                    while(p != slow)
                    {
                        p = p->next;
                        slow = slow->next;
                    }
                    return p;
                }
            }
            return NULL;
        }
    };
  • 相关阅读:
    Java 练习(获取两个字符串中最大相同子串)
    STM32F103 实现 简易闹钟小程序
    STM32F103 实现 LCD显示年月日时分秒星期 并可逐值修改的日期 小程序
    Docker报错之“Failed to get D-Bus connection: Operation not permitted”
    数据结构解析
    每天一条DB2命令-004
    每天一条DB2命令-003
    每天一条DB2命令-002
    ElasticSearch系列
    模块三 GO语言实战与应用-BYTES包与字节串操作(下)
  • 原文地址:https://www.cnblogs.com/-citywall123/p/13435762.html
Copyright © 2011-2022 走看看