• 链表--环形链表(leetcode 141,142


    检测是否有环-leetcode 141

    方法一:哈希表

    我们可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表。常用的方法是使用哈希表

        public boolean hasCycle(ListNode head) {
            ListNode temp1 = head;
            Set<ListNode> set = new HashSet<>();
            while (temp1 != null){
                if(set.contains(temp1)){
                    return true;
                }else {
                    set.add(temp1);
                }
    
                temp1 = temp1.next;
            }
    
            return false;
    
        }
    

    时间复杂度和空间复杂度都是o(n)


    方法二:双指针

    通过使用具有 不同速度 的快、慢两个指针遍历链表,空间复杂度可以被降低至 O(1)。慢指针每次移动一步,而快指针每次移动两步。

    public boolean hasCycle(ListNode head) {
            if (head == null || head.next == null) {
                return false;
            }
            ListNode slow = head;
            ListNode fast = head.next;
            while (slow != fast) {
                if (fast == null || fast.next == null) {
                    return false;
                }
                slow = slow.next;
                fast = fast.next.next;
            }
            return true;
        }
    

    时间复杂度:o(n)
    空间复杂度:o(1)


    返回成环的第一个结点-leetcode 142

    哈希表

        public ListNode detectCycle(ListNode head) {
            ListNode temp = head;
            Set<ListNode> set = new HashSet<>();
            while (temp != null) {
                if(set.contains(temp)){
                    return temp;
                }else {
                    set.add(temp);
                }
                temp = temp.next;
            }
    
            return null;
        }
    

    时空复杂度都为o(n)


    双指针法

    https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/

        public ListNode detectCycle(ListNode head) {
            ListNode fast = head, slow = head;
            while (true) {
                if (fast == null || fast.next == null) {return null;}
                fast = fast.next.next;
                slow = slow.next;
                if (fast == slow) {break;}
            }
            fast = head;
            while (slow != fast) {
                slow = slow.next;
                fast = fast.next;
            }
            return fast;
        }
    

    时间复杂度:o(n)

    空间复杂度:o(1)

  • 相关阅读:
    accpet和connect设置超时
    两个模块的函数如何相互调用?
    有头结点的双向链表
    信号量PV操作实现进程间同步与互斥
    linux read write函数
    函数用指针传参挂死分析
    TCP/IP为什么需要四次握手和三次挥手
    负数在内存中的表示
    malloc的堆内存挂死原因;负数的表示
    Makefiel----no rule to make target 错误问题
  • 原文地址:https://www.cnblogs.com/swifthao/p/13066670.html
Copyright © 2020-2023  润新知