题目:
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
解法:
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
// Solution One -- 按照链表正常删除
var removeNthFromEnd = function(head, n){
let list = new ListNode()
list.next = head
let len = 0, copyList = list
// 先计算链表的长度
while(copyList.next){
copyList = copyList.next
len++
}
let pre , cur = list, i = 0, index = len + 1 - n
while(i < index){
pre = cur
cur = cur.next
index++
}
pre.next = cur.next
return list.next
}
// Solution Two -- 双指针
var removeNthFromEnd4 = function(head, n){
let list = new ListNode(0)
list.next = head
let l = r = list, offset = n + 1
while(offset--){
r = r.next
if(offset > 0 && r === null){
return list.next
}
}
// 右移次数即左应该移动的次数
while(r){
r = r.next
l = l.next
}
l.next = l.next.next
return list.next
}
// Solution Three -- 数组 单次循环
var removeNthFromEnd = function(head, n){
let arr = [head]
for(let cur = head; cur.next; cur = cur.next){
arr.push(cur.next)
}
if(arr.length === 1) return null
if(n > 1){
arr[arr.length - n].val = arr[arr.length - n].next.val
arr[arr.length - n].next = arr[arr.length - n].next.next
}else{
arr[arr.length - n - 1].next = null
}
return arr[0]
}