图解 LeetCode141:链表,你有环嘛?
Posted Rocky0429
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图解 LeetCode141:链表,你有环嘛?相关的知识,希望对你有一定的参考价值。
大家好呀,我是蛋蛋。
今天来切环形链表题,依然是面试高频题。
判断环形链表在思维上稍微复杂一点儿,但是不慌,有我在。
LeetCode 141:环形链表
题意
给定一个链表,判断链表中是否有环。
示例
使用整数 pos 表示链表尾连接到链表中的位置(索引从 0 开始)。
输入:head = [3, 2, 0, -4],pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第 2 个节点。
输入:head = [1],pos = -1
输出:false
解释:链表中没有环。
提示
pos 不作为参数进行传递,仅标识链表的实际情况。
0 <= 链表节点数 <= 10^4
10^-5 <= Node.val <= 10^5
pos 为 -1 或者链表中的一个有效索引。
题目解析
难度简单,解题方法古怪,在实际应用中应该没人脑子瓦特用这种方法。
这种古怪的解题方法就是:快慢指针。
快慢指针,顾名思义,是使用速度不同的指针(可用在链表、数组、序列等上面),来解决一些问题。
这些问题主要包括:
处理环上的问题,比如环形链表、环形数组等。
需要知道链表的长度或某个特别位置上的信息的时候。
快慢指针这种算法证明,它们肯定是会相遇的,快的指针一定会追上慢的指针,可以理解成操场上跑步,跑的快的人套圈跑的慢的人。
一般用 fast 定义快指针,用 slow 定义慢指针。
速度不同是指 fast 每次多走几步,slow 少走几步。一般设定的都是 fast 走 2 步,slow 走 1 步。
当然设置成别的整数也是可以的,比如 fast 走 3 步,slow 走 1 步。
图解
在本题中使用快慢指针:
若是链表无环,那么 fast 指针会先指向 Null。
若是链表有环,fast 和 slow 迟早会在环中相遇。
以 head = [3, 2, 0, -4],pos = 1 为例。
第 1 步:初始化快慢指针。每次 slow 走 1 步,fast 走 2 步。
# 初始化快慢指针
fast = slow = head
第 2 步:slow 移动 1 步,fast 移动 2 步。
while fast and fast.next:
# 快指针移动 2 步,慢指针移动 1 步
fast = fast.next.next
slow = slow.next
第 3 步:同上。
第 4 步:同上。
此时 fast = slow,判断有环,返回 true,结束。
# 快慢指针相遇,有环
if fast == slow:
return True
快慢指针解本题:
-
链表无环,每个节点至多访问 2 次。
-
链表有环,最多移动 n 轮。
所以时间复杂度为 O(n)。
除此以外,只用了额外的 fast 和 slow 两个指针,所以空间复杂度为 O(1)。
代码实现
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 not head or head.next == None:
return False
# 初始化快慢指针
fast = slow = head
# 如果不存在环,肯定 fast 先指向 null
# 细节:fast 每次走 2 步,所以要确定 fast 和 fast.next 不为空,不然会报执行出错。
while fast and fast.next:
# 快指针移动 2 步,慢指针移动 1 步
fast = fast.next.next
slow = slow.next
# 快慢指针相遇,有环
if fast == slow:
return True
return False
Java 代码实现
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
/*算法思想:使用快慢指针相遇解决是否存在环的问题*/
public class Solution
{
public boolean hasCycle(ListNode head)
{
if(head==null)//头指针为空
return false;
ListNode fast=head.next;
ListNode slow=head;
while(fast!=null&&fast.next!=null)
{
fast=fast.next.next;//快指针
slow=slow.next;//慢指针
if(fast==slow)//相遇,则一定存在环,否则慢指针根本跟不上快指针
return true;
}
return false;
}
}
图解链表是否有环到这就结束辣,是不是也不是很难?
仔细揣摩,注意代码细节,多练多敲就可以立于不败之地,臭宝加油。
别忘了我的一键三连么么哒呀。
我是蛋蛋,我们下次见。
以上是关于图解 LeetCode141:链表,你有环嘛?的主要内容,如果未能解决你的问题,请参考以下文章
[leetcode]141. Linked List Cycle判断链表是否有环
LeetCode 141. Linked List Cycle(判断链表是否有环)
141. Linked List Cycle(判断l链表是否有环)(leetcode)
算法分析如何理解快慢指针?判断linked list中是否有环找到环的起始节点位置。以Leetcode 141. Linked List Cycle, 142. Linked List Cycl(代码