swift算法:环形链表

1、描述

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

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

例1:输入:head = [3, 2, 0, -4]  pos = 1

          输出:true

          解释:链表中有一个环,其尾部连接到第二个结点

例2:输入:head = [1, 2]  pos = 0

          输出:true

          解释:链表中有一个环,其尾部连接到第一个结点

 

2、算法:

链表结点:

public class ListNode{
    public var val : Int
    public var next : ListNode?
    public init(_ val : Int){
        self.val = val
        self.next = nil
    }
}

1)哈希表

思想:可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表
           我们遍历所有结点并在哈希表中存储每个结点的引用(或内存地址)。如果当前结点为空结点 nil即以检测到链表尾部的下一个结点,那么我们已经遍历完整个链表,并且该链表不是环形链表。如果当前结点的引用已经存在于哈希表中,那么返回true即该链表为环形链表

时间复杂度:O(n),对于含有n 个元素的链表,我们访问每个元素最多一次。添加一个结点到哈希表中只需要花费O(1) 的时间。

func hasCycle(_ head:ListNode?)->Bool{
        /*
         哈希表
         
         */
        var head = head
        var nodeSeen : [Int:ListNode?] = [:]
        while head != nil {
            if nodeSeen[(head?.val)!] != nil {
                return true
            }else{
                nodeSeen[(head?.val)!] = head
            }
            head = head?.next
        }
        return false
    }

2)双指针

思路:双指针
           我们遍历所有结点并在哈希表中存储每个结点的引用(或内存地址)。如果当前结点为空结点 nil即以检测到链表尾部的下一个结点,那么我们已经遍历完整个链表,并且该链表不是环形链表。如果当前结点的引用已经存在于哈希表中,那么返回true即该链表为环形链表
 时间复杂度:O(n),让我们将 n 设为链表中结点的总数。

func hasCycle2(_ head:ListNode?)->Bool{
        /*
         双指针
         
         */
        if head == nil || head?.next == nil {
            return false
        }
        var slow = head
        var fast = head?.next
        while slow?.val != fast?.val {
            if fast == nil || fast?.next == nil{
                return false
            }
            slow = slow?.next
            fast = fast?.next?.next
        }
        return true
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值