剑指offer23 链表中环的入口节点
这题可以分为两部分,首先判断是否有环,然后如果有环,寻找其入口节点。
自己开始的思路是,首先判断是否有环(快慢双指针),然后如果有环,以每个节点为假想入口节点,判断其是否是入口节点,但是这样时间复杂度O(n^2),略复杂。
然后参考剑指offer的思路:
1.判断是否有环
2.找到环的长度
3.设链表长度l,环长度n,设置两个指针p1,p2 , p1先走n步,则:
p1距离最后一个节点还有l-n的距离,即l-n步后,p1回到环入口节点
而p2距离环入口节点也是l-n步
故p1p2会在环入口节点相遇。
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { ListNode fast = pHead,slow = pHead; while(fast!=null){ fast=fast.next; if(fast!=null) fast=fast.next; else return null;//no loop slow = slow.next; if(fast==slow) break; } //break means there is loop //find the length of loop int loopLength = 1; fast = fast.next; while(slow!=fast){ fast=fast.next; loopLength++; } //find the EntryNode fast=pHead;slow=pHead; for(int i=0;i<loopLength;i++){ fast=fast.next; } while(slow!=fast){ slow=slow.next; fast=fast.next; } return fast; } }
运行时间:25ms
占用内存:9672k
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def EntryNodeOfLoop(self, pHead): # write code here if pHead is None: return None loopLen = self.isLoop(pHead) if not loopLen: return None else: p1 = pHead p2 = pHead for i in range(loopLen): p1= p1.next while p1 is not p2: p1 = p1.next p2 = p2.next return p1 def isLoop(self,pHead): fast = pHead slow = pHead cfast = 0 cslow = 0 while fast.next is not None and fast.next.next is not None: fast = fast.next.next slow = slow.next cfast+=2 cslow+=1 if fast is slow: break if fast is slow: return cfast-cslow else: return 0
运行时间:24ms
占用内存:5708k

浙公网安备 33010602011771号