给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
思路1:
可以循环两次,第一次找到倒数第N个,
第二次循环删除。
比较简单
思路2:
循环一次,如果n=2,则判断tmp->next->next,如果是null,说明找到了,然后直接删除。
扫描二维码关注公众号,回复:
2344952 查看本文章
删除的时候两点注意,必须找到删除哪个节点的前一个节点
- 如果节点存在,必须搞清楚在哪里给front节点赋值
- 如果是删除第一个节点,就直接返回head->next
/**
* 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) {
ListNode* tmp = head;
int nn = n;
while (nn--)
{
if (tmp->next)
tmp = tmp->next;
else{
return head->next;
}
}
ListNode* front;
tmp=head;
while (tmp){
ListNode* tmpp = tmp;
int nn = n;
while (nn--)
{
if (tmpp->next)
tmpp = tmpp->next;
else{
front->next = tmp->next;
return head;
}
}
front = tmp;
tmp = tmp->next;
}
return head;
}
};
调试代码:
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* tmp = head;
int nn = n;
while (nn--)
{
if (tmp->next)
tmp = tmp->next;
else{
return head->next;
}
}
ListNode* front;
tmp = head;
while (tmp){
ListNode* tmpp = tmp;
int nn = n;
while (nn--)
{
if (tmpp->next)
tmpp = tmpp->next;
else{
front->next = tmp->next;
return head;
}
}
front = tmp;
tmp = tmp->next;
}
return head;
}
int main()
{
ListNode first(1);
ListNode second(2);
ListNode thrid(3);
ListNode fourth(4);
ListNode fifth(5);
ListNode* head = &first;
head->next = &second;
head->next->next = &thrid;
head->next->next->next = &fourth;
head->next->next->next->next = &fifth;
head = removeNthFromEnd(head,2);
//cout << "a" << endl;
return 0;
}
人家写的比较简洁: