19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
长度法
/**
* 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) {
int length = 0;
ListNode* p = head;
while (p) {
p = p->next;
length += 1;
}
length -= n;
p = head;
while (length > 1) {
p = p->next;
length--;
}
// 头节点:直接更换头
if (p == head && length == 0) {
return p->next;
} else if (p->next != nullptr) {
p->next = p->next->next;
return head;
} else {
return nullptr;
}
}
};
双指针法:
/**
* 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* p1=head,*p2=head;
int delta = n;//p1和p2之间相差了delta个字符
if(!head){
return nullptr;
}
while(p1->next&&delta>0){
--delta;
p1=p1->next;
}
while(p1->next){
p2=p2->next;
p1=p1->next;
}
// 处理删除逻辑
// 如果要删除的是头节点
if(p2==head&&delta>0){
return p2->next;
}else if(p2->next){
p2->next = p2->next->next;
return head;
}else{
// 如果只有一个节点
return nullptr;
}
}
};
用栈法
/**
* 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) {
stack<ListNode*> st;
ListNode* p = head;
while (p) {
st.push(p);
p = p->next;
}
while (n > 0) {
st.pop();
n--;
}
if (st.empty()) {
return head->next;
} else {
p = st.top();
if (p->next) {
p->next = p->next->next;
return head;
} else {
return nullptr;
}
}
}
};