算法分析(八):环形链表

271 阅读1分钟

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

前言

  • 这道题目比较经典,因为我校招的时候遇到了,但是只是傻乎乎的以为只用一种哈希法做出来就好了,现在想想,人家想要我说的是另一种方法,就是快慢指针。
  • 题目链接:leetcode-cn.com/problems/li… 在这里插入图片描述

第一种解法:哈希法

  • 这个方法我觉得跟暴力法没有什么区别,就是通过一个set集合将所有节点存起来,当有两个节点相同的时候就说明这个链表有环
  • 代码如下:
public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> seen = new HashSet<ListNode>();
        while (head != null) {
            if (!seen.add(head)) {
                return true;
            }
            head = head.next;
        }
        return false;
    }
}

在这里插入图片描述

第二种解法:快慢指针

  • 哈希法就是通过map来记录之前的结点,通过空间来换取时间,而快慢指针就是使用时间来换取空间,因为只用定义两个指针,就可以找出这个链表是否有环
  • 第一步,首先定义慢指针和快指针,快指针在慢指针前面
  • 第二步,进行循环,慢指针走一步,快指针走两步
  • 第三步,进行判断,快指针是否为空,如果访问到有空,那就说明不是环,如果快指针跟慢指针碰到了一起,那就说明,这个链表是环。
  • 代码如下:
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null){
            return false;
        }
        ListNode slow = head;
        ListNode quick = head.next;
        while(slow != quick){
            if(quick == null || quick.next == null){
                return false;
            }
            slow = slow.next;
            quick = quick.next.next;
        }
        return true;
    }
}

在这里插入图片描述

总结

每道算法题都要多看看,多想想,有没有更好或者性能更高的,只有拥有创造力的程序员才叫程序员。