【C++】简单链表求环算法问题

方法一:使用用C++的set库

遍历链表逐一装入set集合,当出现一个结点已经收录在set中时,便找到了该节点

// 算法写在一个类里
class Solution {
    
    
public:
    ListNode* detectCycle(ListNode* head) {
    
    
        set<ListNode*> node_set;
        while (head)
        {
    
    
            if (node_set.find(head) != node_set.end())
                return head;
            node_set.insert(head);
            head = head->next;
        }
        return NULL;
    }
    
};


// 以下为测试
int main() {
    
    
    // c1结点为两链表相交的结点
    ListNode a(1);
    ListNode b(2);
    ListNode c(3);
    ListNode d(4);
    ListNode e(5);
    ListNode f(6);
    ListNode g(7);
    a.next = &b;
    b.next = &c;
    c.next = &d;
    d.next = &e;
    e.next = &f;
    f.next = &g;
    g.next = &c;
    Solution solve;
    ListNode* p = solve.detectCycle(&a);
    if (p)
        cout << "链表有环,环的第一个结点为:" << p->val << endl;
    else
        cout << "链表无环" << endl;
    return 0;
}

结果:

链表有环,环的第一个结点为:3

方法二:快慢指针

初始化两个指针指向头结点,第一个指针速度是1,第二个指针速度是2,即第一个指针每次遍历一个结点,第二个指针每次遍历两个结点,当他们相遇时,便说明了该链表存在环(女少口阿)
而这种办法初步看只能求出是否有环,但求不出具体环的初始位置结点,故需要进一步分析:
求环初始结点

————图片来自小象学院教程课件
重点是这句话:从head和meet(即相遇的点)出发,相遇即为环的起点(女少口阿*2)
代码:

// 算法写在一个类里
class Solution {
    
    
public:
    ListNode* detectCycle(ListNode* head) {
    
    
        ListNode* fast = head; // 快指针
        ListNode* slow = head; // 慢指针
        ListNode* meet = NULL; // 相遇结点
        while (fast)
        {
    
    
            slow = slow->next;
            fast = fast->next;
            if (!fast)
                return NULL;
            fast = fast->next;
            if (fast == slow) {
    
    
                meet = fast;
                break;
            }
        }
        if (meet == NULL)
            return NULL;
        while (head&&meet)
        {
    
    
            if (head == meet)
                return head;
            head = head->next;
            meet = meet->next;
        }
        return NULL;
    }
    
};

就执行用时和内存消耗来看,用set都是比较不友好的,用普通算法就贼省时省内存 |* ̄ー ̄|

ps: 小象学院教程 https://www.bilibili.com/video/BV1GW411Q77S?t=7029&p=2 的笔记
LeetCode题号: 142

猜你喜欢

转载自blog.csdn.net/weixin_44427114/article/details/107794990