• Linked List Cycle


    141. Linked List Cycle

    题目链接:https://leetcode.com/problems/linked-list-cycle/#/description

    题目大意:给定一个链表,判断是否有环,要求不能申请额外的空间

    思路:使用快慢指针。fast指针一次移动两步,slow指针一次移动一步。如果有环,则fast一定会和slow相遇。可以假设fast越过了slow而没有相遇,且slow出于位置i,fast处于位置i+1,那么,在前一步,slow就处于位置i-1,fast处于位置((i+1)-2)或i-1。也就是说,两者相遇了。假定这个链表有一部分不存在环路,长度为k。slow没走p步,fast就会走2p步。因此slow走了k步进入环路部分时,fast已经总共走了2k步,进入环路部分已有k步。由于k可能比环路长度大得多,实际上应该为mod(k, loop_len),并用k表示。即slow处于环中的0步位置,fast处于环中的k步位置,slow落后于fast,相距k步,或者说fast落后于slow,相距loop_len-k步。从fast落后于slow来看,fast现在落后slow loop_len-k步,并且每经过一个移动,fast就走近slow一步,那么两者将在loop_len-k次移动之后相遇。

    算法复杂度:时间复杂度O(n),空间复杂度O(1)

    代码:

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     bool hasCycle(ListNode *head) {
    12         ListNode *slow = head, *fast = head;
    13         while (fast && fast->next) {
    14             slow = slow->next;
    15             fast = fast->next->next;
    16             if (slow == fast)
    17                 return true;
    18         }
    19         return false;
    20     }
    21 };

    评测系统上运行结果:

    142. Linked List Cycle II

    题目链接:https://leetcode.com/problems/linked-list-cycle-ii/#/description

    题目大意:给定一个链表,如果有环,返回环的起点,如果没环,返回nullptr。要求不能修改链表。

    思路:使用快慢指针。fast指针一次移动两步,slow指针一次移动一步。如果有环,则fast一定会和slow相遇。可以假设fast越过了slow而没有相遇,且slow出于位置i,fast处于位置i+1,那么,在前一步,slow就处于位置i-1,fast处于位置((i+1)-2)或i-1。也就是说,两者相遇了。假定这个链表有一部分不存在环路,长度为k。slow没走p步,fast就会走2p步。因此slow走了k步进入环路部分时,fast已经总共走了2k步,进入环路部分已有k步。由于k可能比环路长度大得多,实际上应该为mod(k, loop_len),并用k表示。即slow处于环中的0步位置,fast处于环中的k步位置,slow落后于fast,相距k步,或者说fast落后于slow,相距loop_len-k步。从fast落后于slow来看,fast现在落后slow loop_len-k步,并且每经过一个移动,fast就走近slow一步,那么两者将在loop_len-k次移动之后相遇。假设这个位置为meetspot,meetspot与环路起始处相距k个结点,同时知道链表的头部距离环路起始处也是k个结点。若用一个指针指向meetspot,另一个指针指向链表的头部,两者与环路起始处均相距k个结点,以同样的速度移动,这两个指针就会在k步之后相遇在环路的起始处。

    算法复杂度:时间复杂度O(n),空间复杂度O(1)

    代码:

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     ListNode *detectCycle(ListNode *head) {
    12         ListNode *slow = head, *fast = head;
    13         while (fast && fast->next) {
    14             slow = slow->next;
    15             fast = fast->next->next;
    16             if (slow == fast) {
    17                 fast = head;
    18                 while (slow != fast) {
    19                     slow = slow->next;
    20                     fast = fast->next;
    21                 }
    22                 return fast;
    23             }
    24         }
    25         return nullptr;
    26     }
    27 };

    评测系统上运行结果:

  • 相关阅读:
    C++ 子类调用基类构造函数的简单示例
    无锁编程原子操作 概念记录
    C++ 随手bug 小计
    vector size函数也有大大的坑
    vb.net Try 错误导致 For Each 循环中断
    mysql5.7执行sql语句成功,但是报错Err:1055
    python生成EXE可执行文件的方法
    mysql5.7修改my.ini的默认字符集后,无法重启服务
    日历中常用的功能
    Maven的配置
  • 原文地址:https://www.cnblogs.com/gxhblog/p/6713985.html
Copyright © 2020-2023  润新知