👉️ 力扣原文
题目
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
示例
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
输入:head = [1], n = 1
输出:[]
输入:head = [1,2], n = 1
输出:[1]
分析思路1
使用双指针法:
定义快指针和慢指针,初始时都指向链表的头结点。
快指针先向前移动 N 步。
当快指针到达链表末尾时,慢指针正好指向要删除的结点的前一个结点。
将慢指针的 next 指针指向要删除结点的下一个结点。
题解1
/**
* 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) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode first = dummy;
ListNode second = dummy;
//先将第二个指针向前移动到N个节点
for (int i = 0; i < n; i++) {
second = second.next;
}
//两个指针同时移动直到第二个指针达到末尾
while (second.next != null){
first = first.next;
second = second.next;
}
//此时第一个节点的next节点就是要删除的节点
first.next = first.next.next;
return dummy.next;
}
}
执行结果
分析思路2
先计算链表长度L,随后我们再从头节点开始对链表进行一次遍历,当遍历到第 L−n+1
个节点时,它就是我们需要删除的节点。
题解2
/**
* 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) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode curr = dummy;
int len = getNodeLen(head);
for (int i = 0; i < len-n; i++) {
curr = curr.next;
}
curr.next = curr.next.next;
return dummy.next;
}
public int getNodeLen(ListNode head){
int len = 0;
while (head!=null){
len++;
head=head.next;
}
return len;
}
}
执行结果
分析思路3
栈:
遍历链表的同时将所有节点依次入栈。根据栈「先进后出」的原则,我们弹出栈的第 nnn 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点。
题解3
/**
* 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) {
ListNode dummy = new ListNode(0, head);
Deque<ListNode> stack = new LinkedList<ListNode>();
ListNode cur = dummy;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
for (int i = 0; i < n; ++i) {
stack.pop();
}
ListNode prev = stack.peek();
prev.next = prev.next.next;
ListNode ans = dummy.next;
return ans;
}
}
执行结果