notes/OJ notes/pages/Leetcode Remove-Nth-Node-From-End-of-List.md

184 lines
3.7 KiB
Markdown
Raw Normal View History

2022-07-14 09:33:23 +08:00
# 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:
```expander
tag:#two_pointers
```
- [[Leetcode Intersection-of-Two-Arrays-II]]
- [[Leetcode Merge-Sorted-Array]]
- [[Leetcode Merge-Two-Sorted-Lists]]
- [[Leetcode Middle-of-the-Linked-List]]
- [[Leetcode Move-Zeroes]]
- [[Leetcode Reverse-Words-In-a-String]]
- [[Leetcode Squares-of-a-Sorted-Array]]
- [[Leetcode Two-Sum-II-Input-Array-Is-Sorted]]
- [[Two pointers approach]]
##### Links:
- [Link to problem](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)
- [Explanation](https://leetcode.com/problems/remove-nth-node-from-end-of-list/discuss/1164542/JS-Python-Java-C%2B%2B-or-Easy-Two-Pointer-Solution-w-Explanation)
___
### 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:**
![](https://assets.leetcode.com/uploads/2020/10/03/remove_ex1.jpg)
**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
```cpp
/**
* 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:
```cpp
/**
* 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;
}
};
```