Description
Given a linked list, remove the n-th node from the end of list and return its head.
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.
Follow up
Could you do this in one pass?
Solution 1(C++)
class Solution{
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
int listlen = 0;
ListNode* node = head;
while(node != nullptr){
listlen++;
node = node->next;
}
if(n == listlen) return head->next;
ListNode* pre = nullptr;
ListNode* target = head;
for(int i=0; i<listlen-n; i++){
pre = target;
target = target->next;
}
pre->next = target->next;
return head;
}
};
Solution 2(C++)
class Solution{
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* top = new ListNode(-1);
top->next = head;
ListNode* front = top;
ListNode* behind = top;
ListNode* pre = nullptr;
for(int i=0; i<n; i++) front = front->next;
while(front != nullptr){
front = front->next;
pre = behind;
behind = behind->next;
}
pre->next = behind->next;
return top->next;
}
};
算法分析
解法一
分两次遍历链表,第一次为获得链表长度,然后根据n,确定从前往后数的要删除的结点,第二次遍历就找到要删除的结点就好了。
解法二
仅一次遍历链表,利用前后两个结点,与平分链表、三等分链表的思想非常类似。只不过这里是相同速度的两个结点,但是开始设定两个结点的距离,这样当最前面的结点停下来,后一个结点就能停在我们想要的位置了。
其他类似的题目可参考:
程序分析
略。