给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
现有一个链表 – head = [4,5,1,9],它可以表示为:
进阶:你能尝试使用一趟扫描实现吗?
提示:
- 链表中结点的数目为 sz
- 1 <= sz <= 30
- 0 <= Node.val <= 100
- 1 <= n <= sz
方法一:遍历
思路:
- ◇ 首先计算出当前链表的总长度
- ◇ 要删除的节点下标也就是 length - n
- ◇ 因此循环在下标为 length - n - 1 时
- ◇ 跳过下一个链表节点(注意判断是否为最后一个节点)
- ◇ 如果是最后一个节点 next 置为 空 null
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
const start = head;
let length = 1;
// 计算长度
while(true) {
if(head.next != null) {
length ++;
head = head.next;
}else {
break;
}
}
head = start;
// 如果去除的是第一个节点
if(length - n == 0) {
return head.next;
}
// 循环
for(let i=0; i<length; i++) {
if(i == length-n-1) {
if(i == length-1) {
head.next = null;
} else {
head.next = head.next.next;
}
break;
}
head = head.next;
}
return start;
};
方法二:快慢指针
思路:
- ◇ 快指针先走 n 步
- ◇ 如果 fast 为空,表示删除的是头结点
- ◇ 两个指针一起向后走,直到快指针到达链表尾
- ◇ 慢指针指向下下个节点
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
const start = head;
var fast= head;
var slow = head;
// 快指针先走 n 步
for(let i=0; i<n; i++) {
fast = fast.next;
}
//如果fast为空,表示删除的是头结点
if (fast == null) {
return head.next;
}
// 两个指针一起向后走,直到快指针到达链表尾
while(fast.next != null) {
fast = fast.next;
slow = slow.next;
}
// 慢指针指向下下个节点
slow.next = slow.next.next;
return start;
};