题目描述:
第一种思路:
先扫描链表一次拿到链表长度, 然后再扫描一边通过n拿到需要移出掉的节点的前一位target, 然后设置target.next = target?.next?.next ?? null, 得到结果。
完整代码如下
export function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
if (!head || !head.next) return null;
//head 长度
let length = 1;
let target = null;
let next = head;
while (next.next) {
next = next.next as any;
length++;
}
let next2 = new ListNode();
next2 = head;
for (let i = 0; i < length; ++i) {
if (i === length - n - 1) {
target = new ListNode();
target = next2;
}
next2 = next2?.next!;
}
if (!!target) {
target.next = target?.next?.next ?? null;
} else {
return head.next;
}
return head;
}
第二种思路: 快慢指针
创建快慢两个指针, 快指针先走n步, 然后快慢指针同时开始走, 当快指针走到尾时, 慢指针指向位置为需要移出掉的前一位, 然后同样设置target.next = target?.next?.next ?? null, 得到结果。该方法只需扫描一次链表。
代码如下:
export function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
if (!head || !head.next) return null;
//快指针
let fast = head;
//慢指针
let slow = head;
while (n--) {
//先将快指针 走 n 步
if (!fast.next) {
return head.next;
}
fast = fast.next;
}
while (fast.next) {
fast = fast.next;
slow = slow.next!;
}
slow.next = slow.next!.next;
return head;
}