本文转载自微信公众号《三分钟学会前端》,作者:安姐。转载本文请联系三分钟学习前端公众号。给定一个链表,删除链表的倒数第n个节点,并返回链表的头节点。示例:给定一个链表:1->2->3->4->5,且n=2。当删除倒数第二个节点时,链表变为1->2->3->5。说明:给定的n保证有效。进阶:可以尝试用扫描来实现吗?解决方案:快慢指针解决思路:需要删除链表的最后n个节点,我们需要知道的是最后n+1个节点,然后删除最后一个节点n+1个节点的后继节点即可用过的。步骤:使用2个指针:fastfast指针向前移动n+1步slow指针指向从当前距离开始的第n个节点fast,先head然后,fast和slow同步向前移动,直到fast.next为null,fast是最后一个节点,slow是倒数第n+1个节点。这时问题改成删除链表中slow的后继节点,但是有问题。当链表长度为n时,fast小于n+1个节点位置,所以此时有两种解决方法:创建一个头节点preHead,设置preHead.next=head,这样就可以解决上面的问题,删除倒数第n个节点后,返回的preHead.next就足够了。另一种是,fastfast指针向前移动n步后,判断fast.next是否为null,即fast是否为最后一个节点,如果是,则head为最后第n个节点,这时候问题就可以了简化为删除头节点;如果不是,fast=fast.next,fast是领先一步,slow是倒数第二个n+1节点,也解决了上面的问题。方案一:添加preHead节点contremoveNthFromEnd=function(head,n){letpreHead=newListNode(0)preHead.next=headletfast=preHead,slow=preHead//快速走n+1步while(n--){fast=fast.next}//快慢一起前进while(fast&&fast.next){fast=fast.nextslow=slow.next}slow.next=slow.next.nextreturnpreHead.next};方案二:单独处理倒数n个节点contremoveNthFromEnd=function(head,n){letfast=head,slow=head//快速走n步while(--n){fast=fast.next}if(!fast.next)returnhead.nextfast=fast.next//快、慢一起前进while(fast&&fast.next){fast=fast.nextslow=slow.next}slow.next=slow.next.nextreturnhead};时间复杂度:O(n)空间复杂度:O(1)来源:https://github.com/sisterAn/JavaScript-Algorithms
