Problem: 19. 删除链表的倒数第 N 个结点
文章目录
- 题目描述
- 思路
- 复杂度
- Code
题目描述
思路
1.欲找到倒数第k个节点,即是找到正数的第n-k+1、其中n为单链表中节点的个数个节点。
2.为实现只遍历一次单链表,我们先可以使一个指针p1指向链表头部再让其先走k步,此时再让一个指针p2指向单链表的头部接着使其同p1一起往后走,当p1指向单链表的尾部空指针时(即p1 = null)时停止,此时p2指向的即为正数n-k+1个节点也即使倒数第k个节点;
3.但是在单链表的删除中我们需要找到待删除节点的前驱节点我们在第二步中只是实现了找到倒数第k个节点离删除它还差一步,那我们就先找出倒数第k+1个节点再删除倒数第k个节点
复杂度
时间复杂度:
O ( n ) O(n) O(n);
空间复杂度:
O ( 1 ) O(1) O(1)
Code
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// virtual head node
ListNode dummy = new ListNode(Integer.MIN_VALUE);
dummy.next = head;
ListNode p = dummy;
// find the (n + 1) th node from the end
// then we can remove the n-th node from the end
ListNode x = findFromEnd(dummy, n + 1);
// remove the n-th node from the end
x.next = x.next.next;
return dummy.next;
}
// return the k-th node from the end of the linked list
ListNode findFromEnd(ListNode head, int k) {
ListNode p1 = head;
// p1 moves k steps firstly
for (int i = 0; i < k; ++i) {
p1 = p1.next;
}
ListNode p2 = head;
// p1 and p2 move n - k steps together
while (p1 != null) {
p2 = p2.next;
p1 = p1.next;
}
// p2 is now pointing to the (n - k + 1) -th node,which is the k-th node from the end
return p2;
}
}