LeetCode高频100题刷题记录之——环形链表判断

1 问题描述

给定一个链表,判断链表中是否有环,如果有则返回True,否则返回False。

2 链表拆解法

采用跨节点遍历的方法判断,这样不需要使用额外空间,只需要保存一个终止判断信号(也可以不需要,直接判断)。

首先明确什么情况链表没有环:(1)链表是空的;(2)链表遍历到最后的next是None。

基于此,我们可以考虑跨节点遍历的思想,将链表的 n n n个节点记为标号为 1 , . . . , i . . . , n 1,...,i...,n 1,...,i...,n,对于第 i i i个节点,我们令 L i . n e x t = L i + 1 . n e x t = L i . n e x t . n e x t L_i.next=L_{i+1}.next=L_i.next.next Li.next=Li+1.next=Li.next.next,再令 L i = L i . n e x t L_i=L_i.next Li=Li.next,这样,就跳过了一个节点,到达了第 i + 1 i+1 i+1个节点处,假如链表无环,那在遍历到最后时,可能出现 L i = N o n e , L i . n e x t = N o n e L_i=None,L_i.next=None Li=None,Li.next=None两种情况,出现这两种情况之一,链表都不存在环,否则,链表最终将会变成 L i = L i . n e x t . n e x t L_i=L_i.next.next Li=Li.next.next的情况,也就是链表中最后只有两个节点,这两个节点构成了一个环,因此,假如存在 L i = L i . n e x t . n e x t L_i=L_i.next.next Li=Li.next.next,那这个链表就是有环链表,以此完成对链表是否有环的判断。

python代码实现如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        if (head is None) or (head.next is None):
            return False
        else:
            signal = False
            while signal is False:
                head.next = head.next.next  # 与下一行的顺序不可以调换
                head = head.next
                if head is None:
                    signal = True
                    return False
                elif head.next is None:
                    signal = True
                    return False
                elif head == head.next.next:
                    signal = True
                    return True

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

看了官方题解以后,发现存在一个问题,就是这个算法最终会破坏掉这个链表结构,虽然数据还在,但是无法访问了。

3 快慢指针法

这个应该是判断循环链表很经典的方法,通过快慢指针来进行判断,假如有环,那快慢指针一定会在某个时刻相等,否则就无环。

python代码实现:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        if (head is None) or (head.next is None):
            return False
        else:
            slow = head
            fast = head.next
            signal = False
            while signal is False:
                if slow == fast:
                    signal = True
                    return True
                elif fast is None:
                    signal = True
                    return False
                elif fast.next is None:
                    signal = True
                    return False
                slow = slow.next
                fast = fast.next.next


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

这个方法不会破坏链表。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值