LeetCode | 19. Remove Nth Node From End of List
题目描述
Given a linked list, remove the n-th node from the end of list and return its head.
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.
Follow up:
Could you do this in one pass?
思路
1. Two pass
先遍历一遍,找到链表长度len,第二次从前往后遍历至第len-n个节点,删除它的下一节点,即可
例:1->2->3,n = 2
- 遍历链表,得到len = 3
- remove = len-n = 1
- 删除节点2
- 1->3
2. One pass
要找到倒数第n个节点,首先想到:
用快慢两个指针,快指针先走n步,然后慢指针从头、快指针接着遍历,直至快指针到null节点,此时慢指针在第n个节点上;
但本题不是找到第n个节点,而是需要删除节点。
因此快慢指针应该从head的前一位出发,按上面的步骤,慢指针将会指向第n个节点的前一节点,将慢指针的next指向第n个节点之后的节点,完成删除
例:1->2->3,n = 2
- 新建一个0节点,next指向head,0->1->2->3
- 快指针走n+1步,0(slow)->1->2->3(fast)
- 快慢指针一起遍历至慢指针指向null,0->1(slow)->2->3->null(fast)
- 此时慢指针在要删除节点的前一位
- 删除节点,0->1(slow)->3
代码(One pass)
/**
* 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) {
ListNode pre = new ListNode(0);
ListNode slow = pre, fast = pre;
slow.next = head;
while(n>=0 && fast!=null) {
fast = fast.next;
n--;
}
while(fast!=null) {
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return pre.next;
}
}