https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/6/linked-list/42/
题目中要求只遍历一次,我的思路是,想象一根长度为n的绳子,先把一头定在head,然后遍历,
当超出了长度n的时候,把固定的head的那端向后拉扯。这样,当遍历完了的时候,另一端正好
停留在倒数第n项上。考虑到有可能要删除末尾的节点,我们必须维护两个指针,一个指向倒数
第n个节点,一个指向它的父节点。设这两个指针为nth和nth_1:
有一些特殊情况需要考虑:
1.当删除的是链表的第一个节点,nth_1 == null, nth ==head, nth->next !=null, 此时应当返回nth->next,free(nth)
2. 当链表只有1个节点,nth_1 ==null, nth == head, nth->next==null 此时应当返回null,也就是nth->next, free(nth)
3.当删除的是最后一个节点, nth->next == null,此时应该把nth_1->next=null,返回head, free(nth)
其他情况都应该返回head, nth_1->next = nth->next, free(nth)
下面看一下代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode*p = head;
struct ListNode* nth = head;
struct ListNode* nth_1 = NULL;
struct ListNode* tmp = NULL;
int cnt=0;
while(p){
if(cnt==n){
nth_1 = nth;
nth = nth->next;
}else
cnt++;
p = p->next;
}
if(nth_1 == NULL){
tmp = nth->next;
free(nth);
return tmp;
}else{
if(nth->next==NULL){
nth_1->next = NULL;
free(nth);
}else{
nth_1->next = nth->next;
free(nth);
}
}
return head;
}