LeetCode-19
该题和 面试题 02.02 类似
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
if (head == null || head.next == null) return null;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode fast = dummy;
ListNode slow = dummy;
while (n-- > 0) {
fast = fast.next;
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}
这种题有一个固定的“套路”,因为要获取目标节点的前一个节点,这里创建哑节点,令它的后继节点为head。
之后,fast/slow都指向它(也可以指向head,但这样必须引入一个计数器,判断要删除的是否是头结点。)。先把fast右移n位;之后,再同时移动fast/slow,直到fast指向最后一个节点。此时,fast指到了最后一个节点,slow指到了目标节点的前一个节点(而不是目标节点)。
之后使用slow.next = slow.next.next即可删除目标节点。最后,使用dummy.next返回需要的节点头即可。
而对于面试题 02.02 ,需要返回倒数第k个节点的值,不需要得到目标节点的前驱节点,因此不需要设置哑节点。首先,fast/slow都指向head,之后先移动fast n次,再同时移动fast/slow。直到fast指向null。此时,slow就是目标节点,返回其值即可。代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int kthToLast(ListNode head, int k) {
ListNode slow = head;
ListNode fast = head;
while (k-- >0) {
fast = fast.next;
}
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
return slow.val;
}
}