环形链表I

给定一个链表,判断链表中是否有环。

思路一:
通过一个哈希表,在向后遍历时每遍历一个就加进去,然后判断这个节点之前是否添加过。如果从头到尾都没有则不是环形,有的话就是。

  • 时间复杂度:O(n),对于含有 n个元素的链表,我们访问每个元素最多一次。添加一个结点到哈希表中只需要花费 O(1)的时间。
  • 空间复杂度:O(n),空间取决于添加到哈希表中的元素数目,最多可以添加 n 个元素。
/**
 * 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) {
        HashSet<ListNode> set = new HashSet<ListNode>();
        while(head!=null){
            if(set.contains(head)){
                return true;
            }
            set.add(head);
            head = head.next;
        }
        return false;
    }
}

思路二:
使用双指针,一个跑得快,一个跑得慢。如果有环的话,那么跑的快的一定会追上跑的慢的。如果到头都没有追上,那么就没有环。

  • 时间复杂度:O(n)。没有环便直接到头;如果有环,在环内部两者速度差1,距离假设为k,则耗时K即可追上。
  • 空间复杂度:O(1),我们只使用了慢指针和快指针两个结点,所以空间复杂度为 O(1)。
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null || head.next==null){
            return false;
        }
        ListNode slow = head;
        ListNode fast = head.next;
        while(fast!=null && fast.next!=null){
            if(slow==fast){
                return true;
            }
            slow = slow.next;
            fast = fast.next.next;
        }
        return false;
    }
}
发布了9 篇原创文章 · 获赞 0 · 访问量 123

猜你喜欢

转载自blog.csdn.net/DLC990319/article/details/104474642