我们都直到,双指针法非常好用,比如做合并两个有序数组或者链表等算法,下面介绍一种双指针的新用法,就是判断链表是否有环,对应的其实是leetcode141题,题目描述如下:
题目
给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。
Hash法
其实最简单想得到的就是用一个hash存储节点,遍历链表,如果当前节点在hash表中,表明已经遍历过了,也就表明有环,如果不存在则放入hash表中。
但是这种解法空间复杂度也是O(n)
其实题目还有一个进阶:你能用 O(1)(即,常量)内存解决此问题吗?那么我们就用快慢双指针法来解决
快慢双指针法
我们知道,如果链表有环,我们定义两个指针从同一个节点开始出发,指针1一下子走两步,指针2一下子走1步,如果链表有环,因为指针1走的比较快,那么指针1最后肯定会绕一个圈追上指针1.
我们上面指的一下子走两步的指针1就是快慢双指针中的快指针,而走一步的指针2就是慢指针,根据上面的分析,发现这种方法是可行的,并且空间复杂度也满足O(1).代码也很好实现,如下
/*** 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;ListNode slow = head;while(fast.next!=null&&fast.next.next!=null){fast = fast.next.next;slow = slow.next;if(fast==slow){return true;}}return false;}}
