题目
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示
- 链表中结点的数目为 sz
- 1 <= sz <= 30
- 0 <= Node.val <= 100
- 1 <= n <= sz
题解
题解一
题解一我们采用计算链表长度,通过循环的方式找到要删除节点的下标的前一个结点,改变该节点的后继节点,即删除了目标结点。
计算链表长度方法
public int getLength(ListNode head) {
int length = 0;
while(head != null) {
length++;
head = head.next;
}
return length;
}
当我们遍历到 length - n 的时候,对应的下标就是被删除结点的前一个结点。这个时候我们停止循环,改变该结点的后继节点,即可完成。
代码
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
ListNode cur = dummy;
int length = getLength(head);
for(int i = 0; i < length - n; i++) {
cur = cur.next;
}
cur.next = cur.next.next;
ListNode ans = dummy.next;
return ans;
}
public int getLength(ListNode head) {
int length = 0;
while(head != null) {
length++;
head = head.next;
}
return length;
}
}
题解二
题解二我们采用栈的方法去解决,栈是一个先入后出的的队列,我们可以创建一个栈,遍历链表把所有结点依次入栈,我们弹出的第n个结点,就是我们要删除的结点,此时我们在采用 peek() 方法获取修改被删除节点的前驱节点,修改该该前驱节点的后继节点。
不了解Java中队列的可以先根据下面链接学习一下。
链接:Java队列知识
代码
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 node = stack.peek();
node.next = node.next.next;
ListNode ans = dummy.next;
return ans;
}
}