剑指 Offer II 022. 链表中环的入口节点

第一种方法 实现协议Hashable,Equatable 然后用字典判断是否存在 存在的话说明有环 这个重复的节点就是入口

extension ListNode: Hashable,Equatable {
    public static func == (lhs: ListNode, rhs: ListNode) -> Bool {
        return lhs === rhs
    }
    
    
    public func hash(into hasher: inout Hasher){
        
        hasher.combine(val)
        hasher.combine(ObjectIdentifier(self))
    
    }

   }


class Solution {
    func detectCycle(_ head: ListNode?) -> ListNode? {
        
        if head == nil || head?.next == nil {
            return nil
        }
        
        var tempNode = head
        var dict = Dictionary()
        
        
        while tempNode != nil {
            
            
            if  dict[tempNode!] == nil {
                dict[tempNode!] = 1
            }else {
                return tempNode
            }
            
            tempNode = tempNode?.next
     
        }

        return nil
    

    }

}

然后就是快慢指针算法
有环的话 快慢指针终将相遇
因为每走 1轮,fast 与 slow 的间距 +1,fast 终会追上 slow;

当第一次相遇之后 将fast指针重置在开头。下次相遇的节点就是环的入口

func detectCycle(_ head: ListNode?) -> ListNode? {
        
    
        var fast = head
        var slow = head
        
        while true {
            if fast == nil || fast?.next == nil {
                return nil
            }
            fast = fast?.next?.next
            slow = slow?.next
            
            if fast === slow {
                break
            }
        }
        
        fast = head
        while true {            
            if fast === slow {
                break
            }
            fast = fast?.next
            slow = slow?.next
        }
        
        return fast
        
    }







你可能感兴趣的:(剑指 Offer II 022. 链表中环的入口节点)