给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表:
1->2->3->4->5, 和
n
= 2.
当删除了倒数第二个节点后,链表变为
1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
分析题目:
已知条件:
给定一个链表;
要求的操作:
1.删除链表的倒数第n个节点;
2.返回链表的头节点。
题目所给模版:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
算法分析:
因为得到的是一个未知链表,所以首先需要遍历这个链表。
第一步:遍历链表(遍历算法);
遍历算法不多说,从头节点开始利用head=head->next进行链表遍历;
根据题目要求,本次遍历主要是得到链表中节点个数和其中存储的val;
进行删除算法的设计,此时就要分两种情况:
1.删除的节点为头节点;
2.删除的节点不为头节点;
1.由此前的一题"删除某个节点"的算法可知,删除节点为头节点时,前面没有->next指针域,所以不能用常规的方法删除。
借用上一题的算法:
只需把头节点的val改成与下一个节点的val相等,并把头节点的next改为纸箱第三个节点。
2.当第二种情况时,可直接用常用方法进行删除。
定位算法:
为了不进行多次遍历降低效率,在第一次遍历时,我采用vector存储节点数据,并且利用下标对vector中的元素进行调用访问和修改。
综合所有,得到整体算法:
/**
* 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 *a,*r;
vector<ListNode*> loc;
r=head;
int cnt=0;
while(head->next!=NULL){
loc.push_back(head);
head=head->next;
cnt++;
}
int m=0;
if(n>cnt)// 此时要删除的节点一定是头节点;
{
a=r;
if(cnt==0){
a=NULL;
return a;
}
else{
a->val=a->next->val;
a->next=a->next->next;
return a;
}
}
else//此时删除的一定是除了头节点所节点
{
m=cnt-n;
a=loc[m]->next;
loc[m]->next=loc[m]->next->next;
return r;
}
};
//用ipad写真的难受。。。