BM7. 链表中环的入口结点
描述
输入描述
输入分为2段,第一段是入环前的链表部分,第二段是链表环的部分,后台会根据第二段是否为空将这两段组装成一个无环或者有环单链表输出描述
返回链表的环的入口结点即可,我们后台程序会打印这个结点对应的结点值;若没有,则返回对应编程语言的空结点即可。示例1
输入:
{1,2},{3,4,5}
输出:
3
说明:
返回环形链表入口结点,我们后台程序会打印该环形链表入口结点对应的结点值,即3示例2
输入:
{1},{}
输出:
"null"
说明:
没有环,返回对应编程语言的空结点,后台程序会打印"null"示例3
输入:
{},{2}
输出:
2
说明:
环的部分只有一个结点,所以返回该环形链表入口结点,后台程序打印该结点对应的结点值,即2C++ 解法, 执行用时: 2ms, 内存消耗: 536KB, 提交时间: 2020-12-14
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; */ class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { if(!pHead) return nullptr; ListNode* slow = pHead; ListNode* fast = pHead; int i = 0; while(slow != fast || i == 0) { slow = slow->next; if(!slow) return nullptr; fast = fast->next; if(!fast) return nullptr; fast = fast->next; if(!fast) return nullptr; i++; } slow = pHead; while(slow != fast) { slow = slow->next; fast = fast->next; } return slow; } };
Go 解法, 执行用时: 2ms, 内存消耗: 848KB, 提交时间: 2021-08-04
package main func EntryNodeOfLoop(pHead *ListNode) *ListNode{ if pHead == nil || pHead.Next == nil { return nil } // 快慢指针 fast := pHead last := pHead for fast != nil && fast.Next != nil { fast = fast.Next.Next last = last.Next if fast == last { break } } // 第一次相遇 if last == nil || fast == nil { // 无环 return nil } last = pHead for last != fast { last = last.Next fast = fast.Next } return last }
Go 解法, 执行用时: 2ms, 内存消耗: 852KB, 提交时间: 2021-08-06
package main func EntryNodeOfLoop(pHead *ListNode) *ListNode{ if (pHead == nil) { return nil } slow, fast := pHead, pHead var b bool for slow != nil && fast != nil && fast.Next != nil { slow = slow.Next fast = fast.Next.Next if (slow == fast) { b = true break } } if (!b) { return nil } fast = pHead for fast != slow { fast = fast.Next slow = slow.Next } return fast }
Go 解法, 执行用时: 2ms, 内存消耗: 928KB, 提交时间: 2021-03-06
package main /* * 思路:首先判断链表是否有环,方法是快慢指针; * 接下来计算链表环中有多少个结点(count),方法是选定环中的一个结点然后计数,直到再次回到当前结点; * 最后是找到链表环的入口结点,方法是双指针,一个指针先走count步,然后以相同的速度往前走, * 最终两个指针将在链表环的入口处相遇; */ func EntryNodeOfLoop(pHead *ListNode) *ListNode { markNode := HasLoop(pHead) if markNode == nil { return nil } count := CountNodesInLoop(markNode) slow := pHead fast := pHead for i := 0; i < count; i++ { fast = fast.Next } for slow != fast { slow = slow.Next fast = fast.Next } return slow } // 判断链表是否有环,有环则返回环中的节点,否则返回nil func HasLoop(pHead *ListNode) *ListNode { if pHead == nil { return nil } slow := pHead fast := pHead for fast.Next != nil && fast.Next.Next != nil { slow = slow.Next fast = fast.Next.Next if slow == fast { return slow } } return nil } // 计算链表环中节点的个数 func CountNodesInLoop(markNode *ListNode) int { cur := markNode.Next count := 1 for cur != markNode { count++ cur = cur.Next } return count }
Go 解法, 执行用时: 2ms, 内存消耗: 964KB, 提交时间: 2021-02-22
package main func EntryNodeOfLoop(pHead *ListNode) *ListNode{ if pHead==nil {return pHead} slow,fast :=pHead,pHead for fast !=nil && fast.Next!=nil{ fast = fast.Next.Next slow = slow.Next if fast == slow { break} } if fast ==nil || fast.Next==nil {return nil} slow =pHead for slow!=fast{ slow=slow.Next fast=fast.Next } return fast }