题目
Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
分析
设置两个指针,一个先移动n-1步(为什么是n-1?可以思考一下),另外一个指向头节点,两个一起移动,开始移动的(before)指向最后一个节点时,另外一个(after)指向的就是要删除的结点。
不过此时无法删除这个节点,因为要删除一个节点,必须知道它的前节点。所以在移动时,需要让两个节点保持+1的步长差。
我的做法是:
if (before.next==null) {
return head.next;
} else {
before = before.next;
}
如果before不是最后一个,则让他再向前走一步。否则,直接返回(对应一共只有6个节点,删除倒数第6个,即第一个这种情况)。
这样,当before移动到末尾时,before恰好移动到要删除节点的前一个,直接删除即可。
class Main {
public static void main(String[] args) {
ListNode listNode = new ListNode(1);
listNode.next = new ListNode(2);
listNode.next.next = new ListNode(3);
listNode.next.next.next = new ListNode(4);
listNode.next.next.next.next = new ListNode(5);
removeNthFromEnd(listNode, 1);
}
public static ListNode removeNthFromEnd(ListNode head, int n) {
ListNode before = head;
ListNode after = head;
while (--n>0) {
before = before.next;
}
if (before.next==null) {
return head.next;
} else {
before = before.next;
}
while (before.next!=null) {
after = after.next;
before = before.next;
}
after.next = after.next.next;
return head;
}
static class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
}