19. 删除链表的倒数第 N 个结点
题目描述:
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
提示:
- 链表中结点的数目为
sz 1 <= sz <= 300 <= Node.val <= 1001 <= n <= sz
思路一:
链表长度为len,则从正序的第len-n个节点为被删除节点。找到被删除节点的前一个节点将它的next指向被删除节点的后一个节点即可。
临界问题: 当被删除节点是第一个节点的情况
需要设虚拟节点解决上述临界问题。
/**
* 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) {
if(head == null) return head;
var p = head,len=1;
while(p.next != null) {
p = p.next;
len++;
}
n = len-n;
var node = new ListNode(-1);
node.next = head;
var q = node;
while(n--) q = q.next;
q.next = q.next.next;
return node.next;
};
思路二:快慢指针
两个指针p和q,先让q指针走n步,n步后,再让p和q同时向后每次走一步,直到q到链表结束时终止。此时,p指针所在位置就是待删除节点的前一个节点。(链表长度length,q指针先走了n步,剩余的就有length-n步,第length-n个节点就是待删除节点的前一个节点,所以在q指针先走n步后,p指针才开始走剩余步数就会到达待删除节点的前一个节点)
/**
* 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) {
if(head == null) return head;
var node = new ListNode(-1);
node.next = head;
var p = node,q=node.next;
for(var i = 0; i<n;i++){
q = q.next;
}
while(q!=null) {
p = p.next;
q = q.next;
}
p.next = p.next.next;
return node.next;
};
自述
算法小白一个,记录自己的算法学习之路。如果您发现问题,欢迎留言交流。