<题目描述>
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:给定一个链表: 1->2->3->4->5, 和 n = 2。当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:给定的 n 保证是有效的。
/** 后台定义了这样的链表,在之后可以直接使用。 * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */
<原题链接>
https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
<理明思路>
删除倒数第n个数也即是删除正数第N-n+1(N是链表的总长度)个数,按照这个思路,我们可以先算出链表的长度,然后将指针定位到要删除结点的前一个结点,只需让其将要删除的结点所指向的结点作为新结点(就是前一个点直接指向下下个结点,然后free掉要删除的结点)即可。
<样例代码>
ps:被注释掉的代码的用途是为了更快速准确地排除 调试时的各种bug,不影响程序正常运行,也不影响最终结果。
#include<iostream>
#include<stdlib.h>
using namespace std;
/* 这里为方便调试并且能够在编译器下让程序正常运行,定义了与一个题目中一样的全局变量。
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(n<1) exit(0); /* case1:n的取值错误。 */
ListNode *p,*q;
int length = 1;
q=NULL;
p=head;
while(p->next!=NULL)
{
length++; //得到链表长度。
p=p->next;
}
// cout<<"length="<<length<<endl;
if(n>length) exit(1); /* case2:n取值大于链表长度。 */
p=head; //回到表头。
if(length==1) /* case3:如果链表只有1个结点,依据之前的if,只需删除该节点即可。 */
return NULL;
if(length-n==0 && length!=1) //如果要删除第一个结点(倒数最后一个)
{
head=p->next;
/* 输出调试用:
p=head;
cout<<"新链表为:";
while(p->next!=NULL)
{
cout<<p->val<<" ";
p=p->next;
}
cout<<p->val<<" ";
cout<<endl;
*/
return head;
}
for(int i=1;i<length-n+1;i++)
{
q=p; //将当前p赋给q.
p=p->next; //p指向下一个结点.
}
// cout<<"p->val="<<p->val<<endl;
// cout<<"q->val="<<q->val<<endl;
q->next=p->next;
free(p);
/* 输出调试用:
p=head;
cout<<"新链表为:";
while(p->next!=NULL)
{
cout<<p->val<<" ";
p=p->next;
}
cout<<p->val<<" ";
cout<<endl;
*/
return head;
}
};
另附调试结果用的main函数示例(参考用,通过修改第 6 行和第 28 行的数值来得到不同的运行结果):
int main()
{
struct ListNode *head,*p,*q;
head=NULL;
q=NULL;
for(int i=1;i<=4;i++)
{
p=(struct ListNode*)malloc(sizeof(struct ListNode));
p->val = i;
p->next=NULL;
if(head==NULL) head=p;
else
q->next=p;
q=p;
}
/*输出调试用
p=head;
cout<<"原链表为:";
while(p->next!=NULL)
{
cout<<p->val<<" ";
p=p->next;
}
cout<<p->val<<" ";
cout<<endl;
*/
Solution slu;
slu.removeNthFromEnd(head,2);
return 0;
}
ps:刚刚自学了链表,这道题算是现学现用吧,代码写起来还是有些生疏呢。。。。