栈/队列 解法
一个使用额外空间的解法是利用栈(队列),将所有的节点压入占中栈(队列)中,令当前栈(队列)容量为 。
然后从栈顶(队列头)弹出 个(
个)元素,最后一个出栈(出队列)的元素即是答案。
代码(栈):
import java.util.*;
public class Solution {
public ListNode FindKthToTail (ListNode head, int k) {
Deque<ListNode> d = new ArrayDeque<>();
while (head != null) {
d.addLast(head);
head = head.next;
}
if (d.size() < k) return null;
ListNode ans = null;
while (k-- > 0) ans = d.pollLast();
return ans;
}
} 代码(队列):
import java.util.*;
public class Solution {
public ListNode FindKthToTail (ListNode head, int k) {
Deque<ListNode> d = new ArrayDeque<>();
while (head != null) {
d.addLast(head);
head = head.next;
}
if (d.size() < k) return null;
k = d.size() - k + 1;
ListNode ans = null;
while (k-- > 0) ans = d.pollFirst();
return ans;
}
} - 时间复杂度:
- 空间复杂度:
差值法
我们可以先对链表进行一次完整遍历,拿到总长度 ,最后由
即是倒数第
个节点距离
节点的距离。
代码:
import java.util.*;
public class Solution {
public ListNode FindKthToTail (ListNode head, int k) {
int cnt = 0;
ListNode tmp = head;
while (tmp != null && ++cnt > 0) tmp = tmp.next;
if (cnt < k) return null;
cnt -= k;
while (cnt-- > 0) head = head.next;
return head;
}
} - 时间复杂度:
- 空间复杂度:
快慢指针
事实上,我们还可以使用「快慢指针」进行求解。
起始先让快指针 fast 先走 步,此时
fast 和 slow 之间距离为 ,之后让
fast 和 slow 指针一起走(始终维持相对距离为 ),当
fast 到达链表尾部,slow 即停在倒数第 个节点处。
代码:
import java.util.*;
public class Solution {
public ListNode FindKthToTail (ListNode head, int k) {
ListNode slow = head, fast = head;
while (k-- > 0 && fast != null) fast = fast.next;
if (k != -1) return null;
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
} - 时间复杂度:
- 空间复杂度:
最后
这是我们「剑指 の 精选」系列文章的第 No.69 篇,系列开始于 2021/07/01。
该系列会将牛客网「剑指 Offer」中比较经典而又不过时的题目都讲一遍。
在提供追求「证明」&「思路」的同时,提供最为简洁的代码。
欢迎关注,交个朋友 (`・ω・´)


京公网安备 11010502036488号