zoukankan      html  css  js  c++  java
  • 链表-141-环形链表

    题目:

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

    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

     

    示例 1:

    输入:head = [3,2,0,-4], pos = 1
    输出:true
    解释:链表中有一个环,其尾部连接到第二个节点。


    示例 2:

    输入:head = [1,2], pos = 0
    输出:true
    解释:链表中有一个环,其尾部连接到第一个节点。


     

    进阶:

    你能用 O(1)(即,常量)内存解决此问题吗?

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/linked-list-cycle
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    思路:哈希表和双指针法:

    哈希表

    把节点挨个放到哈希表中,如果链表中有环,则某个节点必然重复出现。用HashSet中的contains判定

    代码如下:

    /**
     * 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> node=new HashSet<>(); //Hash表
            while(head!=null){
                if(node.contains(head)){
                    return true;
                }
                else{
                    node.add(head);
                    head=head.next;
                }
            }
            return false;
        }
    }

    复杂度分析:

    时间复杂度: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) {
          if(head==null || head.next==null){
              return false;
          }
          ListNode low =head;
          ListNode fast=head.next;
          while(low!=fast){
              if(fast==null || fast.next==null){  //这里主要为了防止下面fast=fast.next.next;出现空指针异常
                  return false;
              }
              else{
                  low=low.next;
                  fast=fast.next.next;
              }
          }
          return true;
        }
    }

    复杂度分析:

    链表中不存在环:快指针将会首先到达尾部,其时间取决于列表的长度,也就是 O(n)

    链表中存在环:
    我们将慢指针的移动过程划分为两个阶段:非环部分与环形部分:非环部分为N,环状部分为K;

    近似于快指针多走了一圈环状部分

    因此,在最糟糕的情形下,时间复杂度为 O(N+K),也就是 O(n)。

    空间复杂度:O(1),我们只使用了慢指针和快指针两个结点,所以空间复杂度为 O(1)。

  • 相关阅读:
    Codeforces Round #251 (Div. 2) A
    topcoder SRM 623 DIV2 CatAndRat
    topcoder SRM 623 DIV2 CatchTheBeatEasy
    topcoder SRM 622 DIV2 FibonacciDiv2
    topcoder SRM 622 DIV2 BoxesDiv2
    Leetcode Linked List Cycle II
    leetcode Linked List Cycle
    Leetcode Search Insert Position
    关于vim插件
    Codeforces Round #248 (Div. 2) B. Kuriyama Mirai's Stones
  • 原文地址:https://www.cnblogs.com/Yunus-ustb/p/12891704.html
Copyright © 2011-2022 走看看