LeetCode -- 19. 删除链表的倒数第 N 个结点
一般的删除问题,可以直接删除(找符合条件的,找到了直接删掉),延迟删除(打标记,找完了再删除),栈,双指针
在链表中删除一个节点,要找到其前面一个节点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; } };