Leetcode C++《热题 Hot 100-28》19.删除链表的倒数第N个节点
- 题目
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
- 思路
- 一趟扫描实现,有点困难!时间复杂度可以用空间复杂度替换。
- 方案1: 时间复杂度和空间复杂度均为n,创建一个map,标记每一个节点,找到要删除的index节点
- 方案2: 尽力寻找时间复杂度为n,空间复杂度为1的方案,用双指针的方法,两个指针间隔n,然后同步向前,当一个指针到结尾的时候,另一个节点也到了要删除的位置。有个动画题解特别棒,提供参考链接https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/dong-hua-tu-jie-leetcode-di-19-hao-wen-ti-shan-chu/
- 代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
/*ListNode* removeNthFromEnd(ListNode* head, int n) {
//一趟扫描实现,有点困难!时间复杂度可以用空间复杂度替换。
//方案1: 时间复杂度和空间复杂度均为n,创建一个map,标记每一个节点
map<int, ListNode*> mark;
ListNode* node = head;
int index = 0;
while(node != NULL) {
mark.insert(make_pair(index, node));
index++;
node = node->next;
}
int removeIndex = index - n;
if (index < n)
return head;
if (removeIndex == 0) {
ListNode* newHead = head->next;
head->next = NULL;
delete head;
return newHead;
}
if (removeIndex == index-1) {
ListNode* before = mark[removeIndex - 1];
before->next = NULL;
delete mark[removeIndex];
return head;
}
ListNode* before = mark[removeIndex - 1];
ListNode* after = mark[removeIndex + 1];
before->next = after;
delete mark[removeIndex];
return head;
}*/
//方案2:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* node1;
ListNode* node2;
ListNode* temp = new ListNode(1);
temp->next = head;
int i = 0;
node1 = temp;
node2 = temp;
while (i < n) {
node1 = node1->next;
if (node1 == NULL)
return head;
i++;
}
while(node1->next != NULL) {
node1 = node1->next;
node2 = node2->next;
}
ListNode* deleteNode = node2->next;
node2->next = deleteNode->next;
delete deleteNode;
return temp->next;
}
};