19. 删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
方法一:栈
-
常规思维 算链表长度,然后再找倒数第n个。
-
栈 先压栈,然后弹栈,弹n个
-
双指针,预制位置,j 在 i后面 n的位置,然后两个指针同时移动,就能找到倒数第n个位置
-
ListNode pre = stack.peek();
pre.next = pre.next.next;代码
public ListNode removeNthFromEnd(ListNode head, int n) {
//创建一个新链表
ListNode listNode = new ListNode(0, head);
Stack<ListNode> stack = new Stack<>();
//创建一个辅助变量
ListNode temp = listNode;
while (temp != null) {
//将全部压入栈中
stack.push(temp);
temp = temp.next;
}
for (int i = 0; i < n; i++) {
//弹出栈顶
stack.pop();
}
//返回栈顶元素
ListNode pre = stack.peek();
pre.next = pre.next.next;
ListNode ans = listNode.next;
return ans;
}
方法二:计算链表长度
- 首先从头节点开始对链表进行一次遍历,得到链表的长度 LL。随后我们再从头节点开始对链表进行一次遍历,当遍历到第 L-n+1L−n+1 个节点时,它就是我们需要删除的节点。
- 为了与题目中的 n保持一致,节点的编号从 11 开始,头节点为编号 11 的节点
- 当遍历到第 L-n+1L−n+1 个节点时,它的下一个节点就是我们需要删除的节点,这样我们只需要修改一次指针,就能完成删除操作。
- ListNode pre = stack.peek();
pre.next = pre.next.next;
代码:
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = new ListNode(0, head);
int length = getLength(head);
ListNode cur = pre;
for (int i = 1; i < length - n + 1; i++) {
cur = cur.next;
}
cur.next = cur.next.next;
ListNode ans = pre.next;
return ans;
}
public int getLength(ListNode head) {
int length = 0;
while (head != null) {
length++;
head = head.next;
}
return length;
}