题目:
给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。
注意事项:
链表中的节点个数大于等于n
给出链表1->2->3->4->5->null和 n = 2.,删除倒数第二个节点之后,这个链表将变成1->2->3->5->null.O(n)时间复杂度
思路:
此题与链表倒数第n个结点几乎相同,只不过是找到那个结点后将此结点删除。
先统计出链表总的结点个数a,而倒数第n个结点就是正数第a-n+1个结点。要想删除这个结点,需要将该结点前面的结点(也就是正数第a-n个结点)所指的下一个结点,指向该结点的下一个结点,然后再删除此结点。链表有方向,所以正向寻找结点比较方便。知道了该结点为正数第几个结点后,便可以从链表的头指针开始,逐步找到该结点的前一个结点,再改变前一个结点的指向,然后删除该结点。具体步骤为:
①定义一个指针dummy,令dummy=head,这为了方便最后返回链表的头结点,因为head在统计元素总数的时候位置已经改变。
②定义一个整数a,通过while循环(如果head!=NULL则说明head指向的位置并不是空),统计链表中元素的个数。
③如果要删除的结点就是正数第一个结点,由于dummy就是头结点,如果删除该结点,则最后将不能返回该链表,所以要将dummy=dummy->next。
④如果要删除的结点不是第一个结点,只需找到该结点的前一个结点,改变此结点的下一个指向,删除要删除的结点,最后返回链表。
代码:
/**
* Definition of ListNode
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param head: The first node of linked list.
* @param n: An integer.
* @return: The head of linked list.
*/
ListNode *removeNthFromEnd(ListNode *head, int n) {
// write your code here
ListNode *dummy=head;
int a=0;
int i;
ListNode *p=head;
while(head!=NULL){
a++;
head=head->next;
}
if((a-n)!=0){
for(i=0;i<a-n-1;i++){
p=p->next;
}
ListNode *node=p->next;
p->next=p->next->next;
delete node;
return dummy;
}
else {dummy=dummy->next;
return dummy;}
}
};
感想:
做过“链表中的第n个结点”就基本知道该如何写该程序了,只不过就是多添加了一个删除步骤。在删除结点时要注意要删除的结点是不是第一个结点,对于第一个结点和其他结点要区别对待。