LeetCode -- 19. 删除链表的倒数第 N 个结点

发布时间 2023-08-15 21:48:33作者: 深渊之巅

 

一般的删除问题,可以直接删除(找符合条件的,找到了直接删掉),延迟删除(打标记,找完了再删除),栈,双指针

 

在链表中删除一个节点,要找到其前面一个节点cur, 然后 cur -> next = cur -> next -> next即可

 

方法一:直接删除

  我们先算出链表长度len,要删除倒第n个节点就是删除第len - n个节点。

/**
 * 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 t = head;
        int len = 0;
        while(t) {
            len ++ ;
            t = t -> next;
        }

        auto hd = new ListNode(0, head), cur = hd;
        for(int i = 0; i < len - n; i ++ ) {
            cur = cur -> next;
        }
        cur -> next = cur -> next -> next;
        auto res = hd -> next;

        delete hd;
        return res;
    }
};

 

方法二:栈

  将所有节点入栈,然后出栈n个节点,栈顶元素即为要删除元素的前一个元素

/**
 * 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 hd = new ListNode(0, head), cur = hd;
        stack<ListNode*> stk;
        while(cur) {
            stk.push(cur);
            cur = cur -> next;
        }
        for(int i = 0; i < n; i ++ ) stk.pop();
        auto pre = stk.top();
        pre -> next = pre -> next -> next;

        auto res = hd -> next;
        delete hd;

        return res;
    }
};

 

方法三:双指针

  这里采用快慢指针,让快指针比满指针快n个长度;当快指针指向末尾元素时,满指针指向倒数第n个节点的前一个节点。

/**
 * 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 hd = new ListNode(0, head), cur = hd;
        auto lt = hd, rt = head;

        for(int i = 0; i < n; i ++ ) rt = rt -> next;
        while(rt) {
            rt = rt -> next;
            lt = lt -> next;
        }

        lt -> next = lt -> next -> next;
        auto res = hd -> next;

        return res;
    }
};