一、leetcode算法
1、环形链表
1.1、题目
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
1.2、思路
思路一:此题可以用哈希表来解决,将每一个节点都放入哈希表中,如果有节点重复就证明有环,这种算法的空间复杂度为O(n),即最坏的情况将所有的节点都放入哈希表中。
思路二:可以用快慢指针来解决,定义一个快指针,一个慢指针,快指针每次走两步,慢指针每次走一步,如果没有环,那么快指针会走到头结束,如果有环,快指针会在环中一直循环,等到慢指针也进入环中循环,然后他们会在环中相遇,这就证明有环,这种算法空间复杂度为O(1)。
1.3、答案
public class Solution { public boolean hasCycle(ListNode head) { if(head == null || head.next == null){ return false; } ListNode slow = head; ListNode fast = head.next; while(slow != fast){ if(fast == null || fast.next ==null){ return false; } slow = slow.next; fast = fast.next.next; } return true; } }
复杂度分析
时间复杂度:O(N),其中 N 是链表中的节点数。
当链表中不存在环时,快指针将先于慢指针到达链表尾部,链表中每个节点至多被访问两次。
当链表中存在环时,每一轮移动后,快慢指针的距离将减小一。而初始距离为环的长度,因此至多移动 N 轮。
空间复杂度:O(1)。我们只使用了两个指针的额外空间。