题目描述
给你一个链表,删除链表的倒数第 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
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
删除链表倒数第n个节点,我们只需要找到要删除节点的前一个节点,题目就迎刃而解。
定义两个指针,从图中可以清晰地看出,n就是绿色(pre)与黄色(cur)指针中间的节点数,所以我们让cur先移动n次,与pre间隔n个节点,此时同时移动pre与cur,当cur走到null时,pre的位置即为删除点的前一个节点,我们做删除操作返回头节点即可。
需要注意的是链表节点数为1的情况,因为1<= n <= sz,所以该情况必然返回null。
题解代码
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
//当链表只有一个节点,根据条件,1<= n <= sz,此时删除后链表必为空
if(!head.next) return null;
//定义两个指针分别指向虚拟头结点pre和head节点cur
let ret = new ListNode(-1,head),pre = ret,cur = head;
//让cur指针走n次,与pre指针相隔n个节点
for (let i = 0; i < n; i++) {
cur = cur.next;
}
//让两个指针一起移动,直到cur指向null
while(cur) cur = cur.next,pre = pre.next;
//此时的pre指向的位置即为需要断开点的前一个节点,做断开操作
pre.next = pre.next.next;
return ret.next;
};