【算法】判断链表中是否有环

判断链表是否有环,一般的做法是使用快慢指针的方法来判断,今天想给大家介绍另一种更想法奇特的算法——链表破坏法(仅做参考)

前置说明

链表的存储结构如下,主要包括val和next(为了简单就没有把他变成私有变量)

1 public class ListNode {
2     public int val;
3     public ListNode next;
4     public ListNode(int x) {
5         val = x;
6         next = null;
7     }
8 }

快慢指针法

算法说明:

  1. 设置慢指针slow和快指针fast,初始化都在头结点
  2. fast指针每次比slow指针多走一步
  3. 判断,如果快指针快指针为空,那认为到达了链表顶端,那么就没有环
  4. 判断,如果某一次循环中快指针撞上了慢指针,那么表示形成了闭环(但这并不是环的入口)

优点:

  1. 保持链表结构。

缺点:

  1. 仅能判断是否有环,无法同时找到入口节点信息
 1 public boolean hasCycle(ListNode head) {
 2         ListNode slow = head;
 3         ListNode fast = head;
 4         while (slow!=null && fast!=null && fast.next!=null){
 5             slow = slow.next;
 6             fast = fast.next.next;
 7             if (fast == slow){
 8                 return true;
 9             }
10         }
11         return false;
12     }

 

链表破坏法

算法说明:

  1. 遍历链表,将每个节点都指向head节点
  2. 判断是否当前节点的next已经指向的head节点,如果是,则表示当前节点是环的入口(有环)
  3. 如果一直都没有2的情况发生,且遇到节点为null,表示达到了节点尾部(无环)

优点:

  1. 可以快速判断是否有环以及环入口。

缺点:

  1. 会破坏原始链表结构。
 1 public boolean hasCycle(ListNode head) {
 2         ListNode node = head;
 3         ListNode next = null;
 4         while (node!=null) {
 5             if (node.next == head) {
 6                 return true;
 7             }
 8             next = node.next;
 9             node.next = head;
10             node = next;
11         }
12         return false;
13     }

 

posted @ 2021-09-06 22:10  浙江棋棋  阅读(157)  评论(0编辑  收藏  举报