牛客刷题-go-链表环问题

116 阅读1分钟

快慢针,hash都可以。go写哈希麻烦,没写。

T1. 链表是否有环

思路:

快慢指针+无环链表一定有nil

func hasCycle(head *ListNode) bool {
    if head == nil || head.Next == nil {
        return false
    }
    fast := head.Next.Next
    slow := head.Next
    for fast != slow {
        if fast == nil || fast.Next == nil {
            return false
        }
        fast = fast.Next.Next
        slow = slow.Next
    }
    return true
}

T2. 链表环的入口

思路:

1. 使用hasCycle()判断链表是否有环,并找到相遇的节点。

2. 慢指针继续在相遇节点,快指针回到链表头,两个指针同步逐个元素逐个元素开始遍历链表。

3. 再次相遇的地方就是环的入口。

图片1.png

图片2.png

图片摘自blog.nowcoder.net/sdwwld

func EntryNodeOfLoop(pHead *ListNode) *ListNode {
    hasC, slow := hasCycle(pHead)
    if hasC == false {
        return nil
    } else {
        return getNode(pHead, slow)
    }
}
func hasCycle(pHead *ListNode) (bool, *ListNode) {
    if pHead == nil || pHead.Next == nil {
        return false, nil
    }
    slow := pHead.Next
    fast := pHead.Next.Next
    for fast != slow {
        if fast == nil || fast.Next == nil {
            return false, nil
        }
        fast = fast.Next.Next
        slow = slow.Next
    }
    return true, slow
}
func getNode(pHead *ListNode, slow *ListNode) *ListNode {
    fast := pHead
    for fast != slow {
        fast = fast.Next
        slow = slow.Next
    }
    return slow
}

问题:

是按功能分多个函数写好?还是放一个函数就可以?