Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
我的解法好垃圾
我先确定表长,再用表长减去n,就得到正向要走多少次。
具体细节:先定义fast和slow两个指针,fast一次走2步,slow一次走1部,再定义一个size计数。当fast走到底时,size就是表的一半长度,(flag的目的是为了判断fast能否走2步,这很重要,确定表的长度是奇数还是偶数).确定了表长后,就是正常的链表遍历+删除了
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode *fast=head; ListNode *slow=head; int size=0; bool flag=false; if(head->next==nullptr) { delete head; return NULL; } while(fast->next!=NULL){ fast=fast->next; slow=slow->next; flag=false; size++; if(fast->next!=NULL){ fast=fast->next; flag=true; } } if(flag) size=size*2+1; else size=size*2; int walk = size-n; if(walk==0) { slow=head; head=head->next; delete slow; return head; } else { slow=head; while(walk!=1){ slow = slow->next; walk--; } fast=slow->next; slow->next=fast->next; delete fast; return head; } } };
在ac后,看了discuss里的做法.先放一个大神解法
思路: t2先走n步,才让t1,t2同时走,直到t2走到头。这样,t1走的步数即使正确的了。
还有一点,t1使用二重指针,这样可以优雅的删除节点。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode** t1 = &head, *t2 = head; for(int i = 1; i < n; ++i) { t2 = t2->next; } while(t2->next != NULL) { t1 = &((*t1)->next); t2 = t2->next; } *t1 = (*t1)->next; return head; } };