题目:
给你一个链表,删除链表的倒数第
n
个结点,并且返回链表的头结点示例:
代码思路:
//方法一:
class Solution {
public:
//使用双指针算法
ListNode* removeNthFromEnd(ListNode* head, int n) {
if (head == nullptr) return nullptr; // 如果链表为空,直接返回
// 使用一个哨兵位节点(dummy node)简化头节点被删除的情况
ListNode* dummy = new ListNode(0);
//哨兵位节点的创建,哨兵位节点指向的是链表的头结点
dummy->next = head;
//设立快慢指针
ListNode* fast = dummy;
ListNode* slow = dummy;
// 先让快指针向前移动n+1步
for (int i = 0; i <= n; ++i) {
fast = fast->next;
}
// 快慢指针同时移动,直到快指针到达链表末尾
while (fast != nullptr) {
fast = fast->next;
slow = slow->next;
}
// 此时slow指向要删除的节点的前一个节点
ListNode* temp = slow->next;
slow->next = slow->next->next; // 删除节点
// 释放哨兵位节点
ListNode* newHead = dummy->next;
delete dummy;
// 如果删除的是头节点,newHead已经是指向新头节点的指针
return newHead;
}
};
方法二:
class Solution {
public:
//算出链总长度,再利用链表倒数第n个节点的关系,遍历节点到第n个节点之前的位置
//随后将这个节点的前一个节点链接到,这个节点的后一个节点,然后删除该节点
int getLength(ListNode* head) {
int length = 0;
while (head) {
++length;
head = head->next;
}
return length;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
// new ListNode(0,head)的意思是创建一个初始值是0的节点,这个节点的next指针指向head
ListNode* dummy = new ListNode(0, head);
int length = getLength(head);
ListNode* cur = dummy;
//根据计算,第n个节点的在链表上的位置是 链表长度 - n+1的位置,
//所以这里遍历到这个位置之前即可
for (int i = 1; i < length - n + 1; ++i) {
cur = cur->next;
}
//该节点的 前一个节点 和 该节点的后一个节点链接
cur->next = cur->next->next;
//对哨兵位进行处理
ListNode* ans = dummy->next;
//删除哨兵位
delete dummy;
return ans;
}
};
题目链接:19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)