第一种解答,是很容易就想到的一个做法,知道一个链表的大小,已知要删除倒数的第n个节点,那么我们就知道要正着删除链表的第几个节点了,从头遍历,找到我们要删除的节点;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* 先上直接了当的算法吧。
* };
*/
class Solution {
private:
int TotalNum(ListNode * head){
ListNode * p = head;
int num = 0;
while(p!=NULL){
num ++;
p = p->next;
}
return num;
}
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode * p,*q;
p = q = head;
int num = TotalNum(head);
if(n == num){ //当要删除链表的第一个元素的时候
head = p->next;
free(q);
return head;
}
int t = num - n +1; //链表的顺序执行
int i = 1;
while(p!=NULL)
{
if(i==t)
{
q->next = p->next;
free(p);
break;
}
q = p;
p = p->next;
i++;
}
return head;
}
};
第二种解答,按照LeetCode的solution,只需要遍历链表一次,就能删除想要删除的节点。这种思路有两个指针,我们把他命名为
First 和Second。我们知道当两个人赛跑,他们的速度是一样的,当第一个先跑100米,后面他们两个再一起跑,第二位始终和第一位还是相差100米,所以,我们先让第一个指针遍历n个节点,然后,第二节点再开始遍历,当第一个指针遍历到链表的末尾的时候,第二个指针的下一个节点就是我们要删除的节点了。