欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[M链表] lc19. 删除链表的倒数第N个节点(链表+经典)

程序员文章站 2022-07-12 12:02:45
...

1. 题目来源

链接:19. 删除链表的倒数第N个节点

2. 题目解析

链表删除一定要找到前一个节点,记为 p,则 p->next = p->next->next 就把中间那个节点删除了。假设链表总长为 n,找到倒数第 k 个点的前一个点,即倒数第 k+1 个点。后半段占了 k 个点,那么前半段就是 n-k 个点,由于跳一步就能从第一个点到达第二个点,故,从头结点向后走 n-k-1 步即可注意可能头结点也会被删除,故注意虚拟头结点的使用。

题解中的快慢指针也挺秀的,快指针先走 k+1 步,然后慢指针开始走,快指针到头,则确定倒数第 k+1 个点的位置。

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)

注意:

  • 这里采用了虚拟头结点来处理头结点可能被删除的情况。代码中链表长度 len 是包含虚拟头结点的长度,即所得的 len 要比真实的链表长度多 1。但由于是求倒数第 k 个节点并删除,所以并不影响最终结果。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        auto dummy = new ListNode(-1);
        dummy->next = head;

        int len = 0;
        for (auto p = dummy; p; p = p->next) len ++;

        auto p = dummy;
        for (int i = 0; i < len - n - 1; i ++) p = p->next;
        p->next = p->next->next;
        
        return dummy->next;
    }
};
相关标签: LeetCode LeetCode