返回
倒计时的紧张感——谈LeetCode第19题的解决方案
前端
2023-12-13 13:47:59
导语
当谈到算法和数据结构的经典习题时,LeetCode第19题——删除链表的倒数第N个节点绝对榜上有名。
它的巧妙设计让无数程序员绞尽脑汁,寻找最佳的解决方案。在本文中,我们将踏上这次奇妙的编程旅程,使用JavaScript解锁这个难题。
解析题目:倒数计时
题目
给你一个链表,删除链表的倒数第n个节点,并且返回链表的头结点。
例如,给定一个链表:
1->2->3->4->5
当n=2时,返回链表:
1->2->3->5
题目分析
让我们分解一下题目要求:
- 给定一个链表,意味着我们正在处理一个线性数据结构。
- 需要删除倒数第n个节点,这就意味着我们需要找到链表中从尾部数起第n个节点。
- 删除节点后,我们需要返回修改后的链表的头结点。
解决方案:步步为营
算法概述
我们的解决方案采用双指针法,使用两个指针pre和cur分别指向虚头和头节点。
- 首先,我们需要让cur指针向前移动n步,以找到倒数第n个节点的位置。
- 然后,我们将pre和cur指针一起向后移动,直到cur指针指向null。此时,pre指针指向倒数第n个节点的前一个节点。
- 最后,我们将pre指针指向pre指针的下一个节点,也就是删除了倒数第n个节点后的链表。
代码示例
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* Given a linked list, remove the nth node from the end of the list and return its head.
*
* Example:
* Given linked list: 1->2->3->4->5, and n = 2.
* After removing the second node from the end, the linked list becomes 1->2->3->5.
*
* Note:
* Given n will always be valid.
*
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
const removeNthFromEnd = (head, n) => {
// Create a dummy node to simplify the code
const dummy = new ListNode(0);
dummy.next = head;
// Initialize two pointers, pre and cur
let pre = dummy;
let cur = head;
// Move cur pointer n steps ahead
for (let i = 0; i < n; i++) {
cur = cur.next;
}
// Move pre and cur pointers together until cur reaches the end of the list
while (cur) {
pre = pre.next;
cur = cur.next;
}
// Delete the nth node from the end by skipping it
pre.next = pre.next.next;
// Return the head of the modified list
return dummy.next;
};
复杂度分析
- 时间复杂度:O(n),其中n是链表的长度。因为我们遍历了链表两次,一次是让cur指针移动n步,另一次是让pre和cur指针一起移动。
- 空间复杂度:O(1),因为我们没有使用额外的空间。
结语
LeetCode第19题是一个经典的链表操作问题,希望本文清晰、详细的讲解对各位有所帮助。欢迎大家在评论区分享你们的解题思路和心得,共同提高编程技能。
LeetCode上的算法和数据结构练习非常具有挑战性,但只要你坚持不懈,不断积累经验,你一定会成为一名优秀的程序员!