剑指 Offer 第 23 题-链表中环的入口结点
给一个长度为 n 链表,若其中包含环,请找出该链表的环的入口结点,否则,返回 null。
https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4
方法 1-快慢指针
思路:
- 确定是否有环:两个快慢指针相遇
- 确定环的个数:让指针从相遇的节点再回到这个节点,得到环个数 n
- 确定环入口节点:一个指针先走 n 步,接着和第二个指针同步向前,相遇的点就是入口节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| public class Jz23 { public static void main(String[] args) { final Jz23 jz23 = new Jz23(); final ListNode root = new ListNode(1); final ListNode node3 = new ListNode(3); root .append(new ListNode(2)) .append(node3) .append(new ListNode(4)) .append(new ListNode(5)) .append(node3) ; System.out.println(jz23.EntryNodeOfLoop(root).val); }
public ListNode EntryNodeOfLoop(ListNode pHead) { ListNode meetNode = getMeetNode(pHead); if (meetNode == null) { return null; }
int loopCount = getLoopCount(meetNode);
return getEntryNode(pHead, loopCount); }
private ListNode getEntryNode(ListNode pHead, int loopCount) { ListNode fast = pHead; ListNode slow = pHead;
while (loopCount-- > 0) { fast = fast.next; } while (fast != slow) { fast = fast.next; slow = slow.next; }
return fast; }
private int getLoopCount(ListNode meetNode) { ListNode moveNode = meetNode.next; int count = 1; while (moveNode != meetNode) { moveNode = moveNode.next; count++; } return count; }
private ListNode getMeetNode(ListNode pHead) { ListNode fast = pHead; ListNode slow = pHead;
while (fast != null && slow != null) {
fast = fast.next; if (fast != null) { fast = fast.next; }
slow = slow.next; if (fast != null && fast == slow) { return fast; } } return null; }
public static class ListNode { int val; ListNode next = null;
public ListNode(int val) { this.val = val; }
public ListNode append(ListNode next) { this.next = next; return this.next; } }
}
|
方法 2-hash 法
将值记录到 set 中,首次出现存在的值,对应的就是那个入口点
1 2 3 4 5 6 7 8 9 10 11 12 13
| public ListNode EntryNodeOfLoop(ListNode pHead) { Set<Integer> set = new HashSet<>(); while (pHead != null) { if (set.contains(pHead.val)) { return pHead; } set.add(pHead.val); pHead = pHead.next; } return null; }
|