diff --git a/notes/面试总结.md b/notes/面试总结.md index 9b841f92..35b7aa3a 100644 --- a/notes/面试总结.md +++ b/notes/面试总结.md @@ -24,6 +24,8 @@ * [19. 正则表达式匹配](#19-正则表达式匹配) * [20. 表示数值的字符串](#20-表示数值的字符串) * [21. 调整数组顺序使奇数位于偶数前面](#21-调整数组顺序使奇数位于偶数前面) +* [22. 链表中倒数第 K 个结点](#22-链表中倒数第-k-个结点) +* [23. 链表中环的入口结点](#23-链表中环的入口结点) * [参考文献](#参考文献) @@ -1691,6 +1693,103 @@ class Solution: result = odd + even return result ``` +# 22. 链表中倒数第 K 个结点 + +[NowCoder](https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 解题思路 + +设链表的长度为 N。设两个指针 P1 和 P2,先让 P1 移动 K 个节点,则还有 N - K 个节点可以移动。此时让 P1 和 P2 同时移动,可以知道当 P1 移动到链表结尾时,P2 移动到 N - K 个节点处,该位置就是倒数第 K 个节点。 + +

+ +```java +public ListNode FindKthToTail(ListNode head, int k) { + if (head == null) + return null; + ListNode P1 = head; + while (P1 != null && k-- > 0) + P1 = P1.next; + if (k > 0) + return null; + ListNode P2 = head; + while (P1 != null) { + P1 = P1.next; + P2 = P2.next; + } + return P2; +} +``` + +```python +class Solution: + def FindKthToTail(self, head, k): + # write code here + if head == None: + return None + p1 = head + while p1 and k > 0: + k -= 1 + p1 = p1.next + if k > 0: + return None + p2 = head + while p1: + p1 = p1.next + p2 = p2.next + return p2 +``` + +# 23. 链表中环的入口结点 + +[NowCoder](https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4?tpId=13&tqId=11208&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 题目描述 + +一个链表中包含环,请找出该链表的环的入口结点。要求不能使用额外的空间。 + +## 解题思路 + +使用双指针,一个指针 fast 每次移动两个节点,一个指针 slow 每次移动一个节点。因为存在环,所以两个指针必定相遇在环中的某个节点上。假设相遇点在下图的 y6 位置,此时 fast 移动的节点数为 x+2y+z,slow 为 x+y,由于 fast 速度比 slow 快一倍,因此 x+2y+z=2(x+y),得到 x=z。 + +在相遇点,slow 要到环的入口点还需要移动 z 个节点,如果让 fast 重新从头开始移动,并且速度变为每次移动一个节点,那么它到环入口点还需要移动 x 个节点。在上面已经推导出 x=z,因此 fast 和 slow 将在环入口点相遇。 + +

+ +```java +public ListNode EntryNodeOfLoop(ListNode pHead) { + if (pHead == null || pHead.next == null) + return null; + ListNode slow = pHead, fast = pHead; + do { + fast = fast.next.next; + slow = slow.next; + } while (slow != fast); + fast = pHead; + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + return slow; +} +``` + +```python +class Solution: + def EntryNodeOfLoop(self, pHead): + # write code here + if not pHead: + return None + plist = [] + + while True: + plist.append(pHead) + pHead = pHead.next + if not pHead: + return None + if pHead in plist: + return pHead +``` # 参考文献