3.4 KiB
Leetcode Remove-Nth-Node-From-End-of-List
2022-07-13 09:31
Algorithms:
#algorithm #two_pointers
Data structures:
#DS #linked_list
Difficulty:
#coding_problem #difficulty_medium
Additional tags:
#leetcode #CS_list_need_understanding
Revisions:
N/A
Related topics:
Links:
Problem
Given the head
of a linked list, remove the nth
node from the end of the list and return its head.
Examples
Example 1:
Input: head = [1,2,3,4,5], n = 2 Output: [1,2,3,5]
Example 2:
Input: head = [1], n = 1 Output: []
Example 3:
Input: head = [1,2], n = 1 Output: [1]
Constraints
- The number of nodes in the list is
sz
. 1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
Thoughts
[!summary] This is a #two_pointers problem
#TODO: Understand the two-pointer method
Initially, I thought I use one pointer to remember how long the list is, and use another to traverse there, and remove.
Two pointers method
To finish this in one pass, i need to somehow make the two pointers reach the end at the same time.
We can let fast go n step first, such that when fast comes to the end, slow gets to the Nth node from the last.
To find the 2nd from the last:
slow
|
v
1 -> 2 -> 3 -> 4 -> 5
| ^
|----N----|
fast
Solution
Two pointers method
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
ListNode *pre = new ListNode(0, head);
ListNode *slow = pre;
ListNode *fast = slow;
while (n) {
fast = fast->next;
n--;
}
while (fast->next) {
slow = slow->next;
fast = fast->next;
}
fast = slow->next;
slow->next = slow->next->next;
delete fast;
return pre->next;
}
};
Initial iteration:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
// Use one pointer to get length, another to traverse there
int count = 1;
ListNode *fast = head;
while (1) {
if (fast->next && fast->next->next) {
fast = fast->next->next;
count += 2;
} else if (!fast->next) {
break;
} else {
count += 1;
break;
}
}
count = count - n;
ListNode *pre = new ListNode(0, head);
ListNode *slow = pre;
while (count) {
slow = slow->next;
count--;
}
fast = slow->next;
slow->next = slow->next->next;
delete fast;
return pre->next;
}
};