07 删除链表倒数第n个结点

18 阅读2分钟

题目

image.png

思路1

暴力法

  • 删除倒数第n个结点就是删除正数第len-n个结点。

  • 先扫描一遍链表计算长度len。

  • 再遍历链表,删除第len-n个结点(找到删除结点的前缀,然后删除)

#include<stdio.h>
#include<stdlib.h>
//定义链表结点结构体
typedef struct LinkNode{ 
	int val;
	struct LinkNode *next;
}LinkNode;

//创建链表
LinkNode *creatLinked(){ 
	LinkNode *L=(LinkNode*)malloc(sizeof(LinkNode));
	L->next=NULL;
	LinkNode *rail=L;//尾指针
	
	int val;
	while(1){
		scanf("%d",&val);
		if(val!=-1){
			LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
			s->val=val;
			s->next=NULL;
			rail->next=s;
			rail=s;//尾插法,正序 
		}else
			break;
	} 
	return L;
}
//打印链表
void printList(LinkNode *L){ 
	while(L){
		printf("%d ",L->val);
		L=L->next;
	}
}
//删除倒数第n个结点
LinkNode *remove(LinkNode *head,int k){
	int cnt=0,l,i=1;
	LinkNode *p=head,*q;
	while(p){
		p=p->next;
		cnt++;	
	}//求出链表总长度
	p=head->next;
	while(p){
		if(i==cnt-k-1){
			q=p->next;//给q指针赋值 
			p->next=q->next;
			free(q);
			break;
		}else{
			p=p->next;
			i++;
		}
	}
	return head->next;
}

int main(){
	LinkNode *L=creatLinked();//创建结点
	LinkNode *head=remove(L,2);
	printList(head); 
	return 0;
} 

思路2

优解:快慢指针法

  • 定义快指针和慢指针fast和slow,初始都指向头结点。

  • 让快指针先走n+1步

  • 然后慢指针和快指针同时向后走,当快指针走到链表最后时,慢指针就指向删除结点的前缀,就可以删除了。

#include<stdio.h>
#include<stdlib.h>
//定义链表结点结构体
typedef struct LinkNode{ 
	int val;
	struct LinkNode *next;
}LinkNode;

//创建链表
LinkNode *creatLinked(){ 
	LinkNode *L=(LinkNode*)malloc(sizeof(LinkNode));
	L->next=NULL;
	LinkNode *rail=L;//尾指针
	
	int val;
	while(1){
		scanf("%d",&val);
		if(val!=-1){
			LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
			s->val=val;
			s->next=NULL;
			rail->next=s;
			rail=s;//尾插法,正序 
		}else
			break;
	} 
	return L;
} 
//打印链表
void printList(LinkNode *L){ 
	while(L){
		printf("%d ",L->val);
		L=L->next;
	}
}
//删除链表倒数第n个结点
LinkNode *remove(LinkNode *head,int k){
	LinkNode *fast=head,*slow=head;
	k=k+1;
	while(k>0){
		fast=fast->next;
		k--;
	}
	while(fast){
		slow=slow->next;
		fast=fast->next;
	}
	LinkNode *p=slow->next;
	slow->next=p->next;
	delete p;
	return head->next;
}

int main(){
	LinkNode *L=creatLinked();//创建结点
	LinkNode *head=remove(L,2);
	printList(head); 
	return 0;
}