携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第33天,点击查看活动详情
题目描述
给你一个链表,删除链表的倒数第 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 <= 300 <= Node.val <= 1001 <= n <= sz
解题思路——遍历
根据题目可以知道找的是倒数第 n 个节点,这个 n 一定比节点数量小。
那么我们简单的,像排队点人头一样,如果正常我们想要找到倒数第 n 个人,直接从最后一个开始数就完事了,但是单链表只能从头开始遍历,而且不能从后一个节点找到前一个节点,所以如果我们想找到倒数第 n 个人的话,我们首先要知道链表的总节点数 size,然后从头开始数,数到 size-n 个时,这个人就是倒数第 n 个人了。
题解
var removeNthFromEnd = function(head, n) {
let cnt = 0, temp = head;
while(temp) {
cnt++;
temp=temp.next;
}
if(n % cnt === 0) {
return head.next || null;
}
cnt = cnt - n;
temp = head;
while(--cnt) {
temp=temp.next;
}
temp.next = (temp.next && temp.next.next) || null;
return head;
};
解题思路——双指针
单链表的解法一般是双指针,也称作快慢指针。
双指针一般是以不同速度移动,一个指针跑的快一些,另一个指针跑的慢一些;还有种是一个指针先跑,另一个指针在某个条件触发时才进行移动。
那么这道题就可以用双指针解了。题目要求我们删除的是倒数第 n 个节点,我们可以定义一个快指针,抢跑于慢指针 n 步的距离,随后两个指针以 相同的速度 跑,这样一来,当快指针跑到终点的时候,慢指针差了快指针 n 步,此时的慢指针所在的位置就相当于倒数第 n 个节点了。
题解
/**
* 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) {
let slow = head, fast = head.next;
while(--n) {
fast = fast.next;
}
if(!fast){
return head.next;
}
while(fast.next) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
};