「这是我参与12月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 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
进阶: 你能尝试使用一趟扫描实现吗?
递归
思路
使用递归的思想: 这里我们定义了三个变量,
-
pre用来保存删除节点的前一个节点,
-
next用来保存删除节点的下一个节点,
-
index用来记录当前是倒数第几个节点
最后进行判断,如果存在pre证明不是删除第一个节点,先处理pre.next = next 然后返回头节点head
如果pre不存在证明删除的是头节点,直接返回head.next
var removeNthFromEnd = function (head, n) {
var pre = null
var next = null
var index = 0
function remove(head, n) {
if (!head) {
index++
return
}
remove(head.next, n)
if (index === n) {
next = head.next
}
if (index === n + 1) {
pre = head
}
index += 1
}
remove(head, n)
if (pre) {
pre.next = next
return head
} else {
return head.next
}
};
哈希表思路
思路
这里我们用数组来保存我们遍历链表的每一个节点得到数组arr
同上寻找pre节点以及next节点
-
需要删除的n节点的下标为arr.leng-n
-
所以pre节点的下标为arr.length-n-1
-
next节点的下标为arr.length-n+1
这里需要注意的是找到pre和next后再去删除n节点,因为提前删除n节点会影响寻找pre和next的下标,导致错误,所以放在最后删除
最后看数组中是否还有值,有就直接返回第一个节点,否则就返回null
var removeNthFromEnd = function (head, n) {
var pre = null
var next = null
var arr = []
while (head) {
arr.push(head)
head = head.next
}
if (arr[arr.length - n + 1]) {
next = arr[arr.length - n + 1]
}
if (arr[arr.length - n - 1]) {
pre = arr[arr.length - n - 1]
pre.next = next
}
arr.splice(arr.length - n, 1)
var res = arr[0] ? arr[0] : null
return res
};