题目
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
一. 两趟扫描实现
第一趟扫描时,获取链表的长度,计算删除的位置,第二趟时删除计算出的位置即可。
js实现
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
var len = 0
var node = head
// 获取长度
while (node !== null) {
node = node.next
len++
}
// 如果要删除的位置为头节点
if (len === n) {
return head.next
}
// 获取要删除的位置并删除
node = head
var index = len - n
var prev
for (var i=0;i<index;i++) {
prev = node
node = node.next
}
prev.next = node.next
return head
}
复杂度分析
时间复杂度:O(2n)
空间复杂度:O(1)
测试结果
✔ Accepted
✔ 208/208 cases passed (76 ms)
✔ Your runtime beats 73.39 % of javascript submissions
✔ Your memory usage beats 27.74 % of javascript submissions (34 MB)
二. 一趟扫描实现
扫描时,使用一个距离当前节点为n
的节点,当当前节点到达末尾时,另一节点到达要删除的位置。
js实现
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
var node = head
for (var i=0;i<n;i++) {
node = node.next
}
if (node === null) {
return head.next
}
var target = head
while (node.next !== null) {
target = target.next
node = node.next
}
target.next = target.next.next
return head
}
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
测试结果
✔ Accepted
✔ 208/208 cases passed (64 ms)
✔ Your runtime beats 95.72 % of javascript submissions
✔ Your memory usage beats 32.01 % of javascript submissions (34 MB)