【双指针】Leetcode --- NO.141 环形链表(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) {
    }
}

题目分析

  • 代码中给定了一个头结点,那么就是通过这个头结点遍历
  • 一种解法是,将遍历过的结点做一个标记,放入读过的结点集合中,直到全部读完,如果都还没有读到已经读过的结点,那就说明没有环
  • 第二种解法就是双指针法,一个指针移动快,一个指针移动慢,如果有环形,那么两个指针一定能够遇到

解法分析

  • 如果使用第一种解法,对于含有 n 个元素的链表,我们访问每个元素最多一次;空间取决于添加到哈希表中的元素数目,最多为n,所以时间复杂度和空间复杂度都是 O(N)
  • 如果使用第二种解法:【分析来自官方题解】
    在这里插入图片描述

代码

  • 解法一,来自官方
public boolean hasCycle(ListNode head) {
	// 已经读取过的结点集合
    Set<ListNode> nodesSeen = new HashSet<>();
    // 遍历所有结点
    while (head != null) {
    	// 如果当前读取的结点已经读取过了,那就说明有环
        if (nodesSeen.contains(head)) {
            return true;
        } else {
        	// 如果没有读取过,就放入读取过的结点集合
            nodesSeen.add(head);
        }
        // 移动指针
        head = head.next;
    }
    // 没有环返回false
    return false;
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/linked-list-cycle/solution/huan-xing-lian-biao-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 解法二,双指针法
public class Solution {
    public boolean hasCycle(ListNode head) {
    	// 当空结点和只有一个结点的时候,直接返回false
        if (head == null || head.next == null) return false;
        // 双指针,一快一慢
        ListNode a = head, b = head.next;
        // 当链表没有遍历到结尾时
        while(a != null && b != null && b.next != null){
        	// 如果两个指针相遇
            if(a == b) {
                return true;
            }
            // 没有相遇就移动指针
            // 慢指针一次移动一个位置
            a = a.next;
            // 快指针一次移动两个位置
            b = b.next.next;
        }
        // 如果遍历完了还没有相遇就说明没有环
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/Kobe_k/article/details/107500051