sword_for_offer/docs/剑指 Offer 22. 链表中倒数第 k 个节点.md
第一时间想到的解法:
使用双指针则可以不用统计链表长度。
{:width=400}
former 、后指针 latter ,双指针都指向头节点 head 。former 先向前走 $k$ 步(结束后,双指针 former 和 latter 间相距 $k$ 步)。former 和 latter 每轮都向前走一步,直至 former 走过链表 尾节点 时跳出(跳出后, latter 与尾节点距离为 $k-1$,即 latter 指向倒数第 $k$ 个节点)。latter 即可。<,,,,,,,>
former 走了 $N$ 步, latter 走了 $(N-k)$ 步。former , latter 使用常数大小的额外空间。class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
former, latter = head, head
for _ in range(k):
former = former.next
while former:
former, latter = former.next, latter.next
return latter
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode former = head, latter = head;
for(int i = 0; i < k; i++)
former = former.next;
while(former != null) {
former = former.next;
latter = latter.next;
}
return latter;
}
}
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode *former = head, *latter = head;
for(int i = 0; i < k; i++)
former = former->next;
while(former != nullptr) {
former = former->next;
latter = latter->next;
}
return latter;
}
};
本题没有 $k>$ 链表长度的测试样例 ,因此不用考虑越界。考虑越界问题的代码如下:
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
former, latter = head, head
for _ in range(k):
if not former: return
former = former.next
while former:
former, latter = former.next, latter.next
return latter
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode former = head, latter = head;
for(int i = 0; i < k; i++) {
if(former == null) return null;
former = former.next;
}
while(former != null) {
former = former.next;
latter = latter.next;
}
return latter;
}
}
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode *former = head, *latter = head;
for(int i = 0; i < k; i++) {
if(former == nullptr) return nullptr;
former = former->next;
}
while(former != nullptr) {
former = former->next;
latter = latter->next;
}
return latter;
}
};