zoukankan      html  css  js  c++  java
  • LeetCode 141:环形链表 Linked List Cycle

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

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

    Given a linked list, determine if it has a cycle in it.

    To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

    示例 1:

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

    img

    示例 2:

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

    img

    示例 3:

    输入:head = [1], pos = -1
    输出:false
    解释:链表中没有环。
    

    img

    进阶:

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

    Follow up:

    Can you solve it using O(1) (i.e. constant) memory?

    解题思路:

    ​ 从头节点向后遍历整个链表只要遍历到节点为 null ,就证明不是环形,而如果遍历到一个节点的地址之前存在过就证明有环。

    1、哈希表:

    解决重复问题最容易想到的数据结构就是哈希表,哈希表添加节点时只要发现节点已经存在了,证明就有环形链表。并且哈希表查找和插入复杂度都为O(1),但是空间复杂度会随着原链表长度而增大:O(n),总的来说:

    • 时间复杂度:O(n),虽然哈希表的查找和添加操作的时间复杂度是 O(1) ,但是先需要遍历链表然后插入,遍历的复杂度是O(n)
    • 空间复杂度:O(n),最多需要保存链表的 n个节点

    2、双指针:

    这道题就如同小学跑步问题,假设有两个人(双指针)一个快一个慢,不停地向前跑,如果跑得快的那个最后到终点了(遇到空节点 null),就证明是直线跑道(没有环形链表)。

    如果是存在环形跑道(环形链表):两个人一起跑步(双指针)一个快一个慢,那么这两个人因为速度不同,在环形跑道里跑得快的那个人一定会追上慢的。即两个指针相遇了,证明存在环形链表。

    空间复杂度为O(1),即进阶要求的常量内存。

    哈希表解题:

    Java:

    public class Solution {
        public boolean hasCycle(ListNode head) {
            if (head == null) return false;//如果是空链表直接返回
            Set<ListNode> nodeSet = new HashSet<>();//构造哈希表
            while (head.next != null) {//链表下一个不为空
                if (nodeSet.contains(head)) return true;//哈希表包含该节点则存在环形链表
                nodeSet.add(head);//加入节点
                head = head.next;//下移一位
            }
            return false;
        }
    }
    

    Python:

    class Solution(object):
        def hasCycle(self, head):
            """
            :type head: ListNode
            :rtype: bool
            """
            if head is None:
                return False
            hashSet=set()#构造集合
            while(head.next is not None):
                if head in hashSet:#是否已存在
                    return True
                hashSet.add(head)
                head=head.next
            return False
    

    双指针解题:

    Java:

    public class Solution {
        public boolean hasCycle(ListNode head) {
            if (head == null || head.next == null) {
                return false;
            }
            ListNode slow = head;
            ListNode fast = head;
            while (fast != null && fast.next != null) {//快指针及其下一位是否为空
                slow = slow.next;
                fast = fast.next.next;
                if (slow == fast) {//如果相遇,存在环形链表
                    return true;
                }
            }
            return false;
        }
    }
    

    Python:

    class Solution(object):
        def hasCycle(self, head):
            """
            :type head: ListNode
            :rtype: bool
            """
            if head is None or head.next is None:
                return False
            slow, fast = head, head
            while fast is not None and fast.next is not None:
                slow, fast = slow.next, fast.next.next
                if slow == fast:
                    return True
            return False
    

    扩展:

    python 中is 与 == 区别 :

    is 用于判断两个变量引用对象(即内存地址)是否为同一个, == 用于判断引用变量的值是否相等。

    而Python出于对性能的考虑,不可变对象、同一代码块中的对象、值相同的对象,都不会重复创建,而是直接引用已经存在的对象。

    欢迎关注公众号:爱写bug,一起学习。

    爱写bug.png

  • 相关阅读:
    JAVA数据结构--ArrayList动态数组
    LeetCode记录之35——Search Insert Position
    LeetCode记录之28——Implement strStr()
    LeetCode记录之27——Remove Element
    LeetCode记录之26——Remove Duplicates from Sorted Array
    LeetCode记录之21——Merge Two Sorted Lists
    LeetCode记录之20——Valid Parentheses
    LeetCode记录之14——Longest Common Prefix
    JMeter学习笔记01-安装环境
    Python3学习笔记35-编程练习题
  • 原文地址:https://www.cnblogs.com/zhangzhe532/p/11193185.html
Copyright © 2011-2022 走看看