给你一个链表,删除链表倒数第n个节点,返回链表头节点。Advanced:可以尝试使用one-passscan实现吗?示例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]解题思路使用速度指针。删除链表的最后第n个节点,需要知道最后第n+1个节点,然后删除最后第n+1个节点的后继节点。使用2个指针,fast指针向前移动n+1步,slow指针指向fast当前距离下的第n个节点,初始为head。然后,fast和slow同步向前移动,直到fast.next为null。此时fast是最后一个节点,slow是倒数第n+1个节点,然后直接删除slow的后继节点即可。但是有一种情况,就是当链表长度为n时,快速指针无法前进到n+1的位置,所以这时候有两种解决方案:一种解决方案是创建一个头节点preHead并设置preHead.next=head,这样上面的问题就可以解决了。删除最后第n个节点后,返回preHead.next;还有一种方案,fast指针前进n步后,判断fast.next是否为null,即fast是否为最后一个节点,head为最后第n个节点,直接删除head节点即可。如果不是,fast=fast.next,快进一步,接着正常逻辑处理;添加preHead节点的代码实现:functionremoveNthFromEnd(head,n){letpreHead=newListNode(0);preHead.next=head;让fast=preHead,slow=preHead;//fast指针先走n+1步while(n--){fast=fast.next;}//快指针和慢指针一起向前移动while(fast&&fast.next){fast=fast.next;慢=慢.next;}//删除节点slow.next=slow.next.next;returnpreHead.next;}单独处理倒数第n个节点:functionremoveNthFromEnd(head,n){letfast=head,slow=head;//fast指针先走n步while(--n){fast=fast.next}//如果链表长度为n,直接删除头节点if(!fast.next)returnhead.next;//快速指针再向前一步fast=fast.next;//快指针和慢指针一起向前移动while(fast&&fast.next){fast=fast.next;慢=慢.next;}//删除节点slow.next=slow.next.next;returnhead;}??时间复杂度O(n),空间复杂度O(1)。对了,n--和--n的写法不同:letn=10;//从9到0,共循环10次,最后n=-1while(n--){console.log("Testcontent",n)}n=10;//从9到1,共循环9次,最后n=0while(--n){console.log("测试内容",n)}
