给定一个链表,删除链表的顺数及倒数第 n 个节点。
示例1:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了顺数第2个及倒数第2个节点后,链表变为 1->3->5.
示例2:
给定一个链表: 1->2->3->4->5, 和 n = 3.
当删除了顺数第3个及倒数第3个节点后,链表变为 1->2->4->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
#include<iostream>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode() : val(0), next(NULL) {}
ListNode(int x) : val(x), next(NULL) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
ListNode* removeNth(ListNode* head, int n) {
if(head==NULL||n<=0)
return head;
ListNode *temp=new ListNode(0);//建立虚拟头节点,以防止删除头结点
temp->next=head;
ListNode *p=temp,*q=temp,*pre;//让p指针比q指针先跑n次
for(int i=0;i<n;i++){
if(p==NULL){
return head;//说明链表长度小于n
}else{
pre=p;
p=p->next;
}
}
//p,q一起向前跑,直到p->next为空
while(p->next){
p=p->next;
q=q->next;
}
//正数和倒数不是同一个数
if(pre->next!=q->next){
q->next=q->next->next;//必须先删出倒数的,再删除正数的,不然会断链
pre->next=pre->next->next;
}else{
//删出q的next节点
q->next=q->next->next;
}
return temp->next;
}
};
ListNode *createByTail()
{
ListNode *head;
ListNode *p1,*p2;
int n=0,num;
int len;
cin>>len;
head=NULL;
while(n<len && cin>>num)
{
p1=new ListNode(num);
n=n+1;
if(n==1)
head=p1;
else
p2->next=p1;
p2=p1;
}
return head;
}
void displayLink(ListNode *head)
{
ListNode *p;
p=head;
cout<<"head-->";
while(p!= NULL)
{
cout<<p->val<<"-->";
p=p->next;
}
cout<<"tail\n";
}
int main()
{
ListNode* head = createByTail();
int n;
cin>>n;
head=Solution().removeNth(head,n);
displayLink(head);
return 0;
}