[M链表] lc19. 删除链表的倒数第N个节点(链表+经典)
程序员文章站
2022-07-12 12:02:45
...
1. 题目来源
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;
}
};
上一篇: 求x的n次幂算法Pow(x, n)
下一篇: 压缩感知模型及稀疏信号的生成