想法一
先用tail指针找尾,计算出节点个数,再根据倒数第N个指定删除
想法二
根据进阶的要求,只能遍历一遍链表,那刚刚想法一就做不到
首先,我们要在一遍内找到倒数第N个节点,所以我们设置slow和fast两个指针,先让fast指针往后走N个节点,然后两个指针在一起走,直到fast指针走到尾节点,此时slow便指向倒数第N个节点
然后,找到指定节点后,要分情况删除:头删,中间删除,尾删
头删:当fast指针为NULL时,则为头删
尾删:当slow指针下一个节点就是fast指针时,则为尾删
中间删除:此时仅仅一个slow指针还不能完成中间节点的删除,所以增加一个medium指针,让它位于slow的下一个节点,则可以实现中间删除
完整代码如下:
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) { struct ListNode* slow = head; struct ListNode* fast = head; struct ListNode* medium = head->next; while (n--) { fast = fast->next; } while (fast && fast->next) { slow = slow->next; medium = medium->next; fast = fast->next; } if (!fast) { //头删 head = slow->next; free(slow); } else if(slow->next == fast) { //尾删 slow->next = NULL; free(fast); } else { //中间删除 slow->next = medium->next; free(medium); } return head; }