19.删除链表的倒数第n个节点
描述:

思路:
- 如果将这个题中的链表看做为数组, 解题方法将很简单, 但是链表相对于数组, 无法直接知道链表的长度和链表每个元素的下标, 只有根据每个元素的指针域进行遍历, 此题即考察这一点.
- 理所当然的, 可以想到, 先获取链表的整体长度
len, 之后遍历至len - n + 1将此处的元素删除即可. - 另一种思路双指针法, 快指针先移动n + 1个位置, 此时快指针和慢指针之间即相隔n个元素, 之后进行遍历, 快指针和慢指针同时移动, 到快指针指向null时, 慢指针即指向待删除的元素, 遍历结束, 删除慢指针指向的元素即可.
代码:
-
求链表长度法
/* * @lc app=leetcode.cn id=19 lang=cpp * * [19] 删除链表的倒数第 N 个结点 */ // @lc code=start /** * 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: int getLength(ListNode *head) { int length = 0; while (head->next != nullptr) { head = head->next; length++; } return length; } ListNode *removeNthFromEnd(ListNode *head, int n) { ListNode *dummy = new ListNode(0, head); int ListNodeLen = getLength(head); ListNode *cur = dummy; for (int i = 0; i < ListNodeLen - n + 1; i++) { cur = cur->next; } cur->next = cur->next->next; ListNode *result = dummy->next; delete dummy; return result; } };
-
双指针法:
/* * @lc app=leetcode.cn id=19 lang=cpp * * [19] 删除链表的倒数第 N 个结点 */ // @lc code=start /** * 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) { ListNode *fast = head; ListNode *slow = head; for (int i = 0; i < n; i++) { fast = fast->next; } if (fast == nullptr) { return head->next; } while (fast->next != nullptr) { fast = fast->next; slow = slow->next; } slow->next = slow->next->next; return head; } };