自学内容网 自学内容网

[数据结构]链表OJ--环形链表判断是否有环(快慢指针法)

141. 环形链表 - 力扣(LeetCode)

这里我采用的是快慢指针法,这是我认为最容易理解的方法,这个方法的思路是这样的.

我们可以定义两个指针一个快一个慢,如果这个链表有环,则快慢指针一定会相遇.

这里我画图举个例子:

我们很明显的可以看出,有环链表,快指针和慢指针存在相遇.

快指针跑得快,慢指针跑得慢。当慢指针和快指针从链表上的同一个节点开始移动时,如果该链表中没有环,那么快指针将一直处于慢指针的前方;如果该链表中有环,那么快指针会先于慢指针进入环,并且一直在环内移动。等到慢指针进入环时,由于快指针的速度快,它一定会在某个时刻与慢指针相遇,即套了慢指针若干圈。

接下来就让我们的想法实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    
}

它默认给我们创建了一个链表,给了这个链表的表头的地址

我们想可以考虑给的链表为空的情况,而且我们观察例子,我们可以看出存在只有一个头的没有下一个节点的链表,所以我门要对这两种情况进行判断

if(head==NULL||head->next==NULL)
{
    return false;
}

然后我们创建快慢指针:

struct ListNode* slow = head;
struct ListNode* fast = head;

然后我们让指针跑起来如果最后有一个指针跑到NULL说明,这个链表没有环,如果快慢指针不相等就接着跑,知道两个指针相遇.说明有环

  do
    {
        if (fast == NULL || fast->next == NULL)
         {
            return false;
        }
        slow = slow->next;
        fast = fast->next->next;
    }while (slow != fast);
    return true;

最后组合起来

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode* head) {
    if (head == NULL || head->next == NULL) {
        return false;
    }
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    do
    {
        if (fast == NULL || fast->next == NULL)
         {
            return false;
        }
        slow = slow->next;
        fast = fast->next->next;
    }while (slow != fast);
    return true;
}


原文地址:https://blog.csdn.net/2301_80017277/article/details/136435910

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!