diff --git a/OJ notes/pages/Leetcode Middle-of-the-Linked-List.md b/OJ notes/pages/Leetcode Middle-of-the-Linked-List.md index 80b237e..594b6c0 100644 --- a/OJ notes/pages/Leetcode Middle-of-the-Linked-List.md +++ b/OJ notes/pages/Leetcode Middle-of-the-Linked-List.md @@ -18,6 +18,15 @@ tag:#two_pointers ``` +- [[Leetcode Intersection-of-Two-Arrays-II]] +- [[Leetcode Merge-Sorted-Array]] +- [[Leetcode Merge-Two-Sorted-Lists]] +- [[Leetcode Move-Zeroes]] +- [[Leetcode Remove-Nth-Node-From-End-of-List]] +- [[Leetcode Reverse-Words-In-a-String]] +- [[Leetcode Squares-of-a-Sorted-Array]] +- [[Leetcode Two-Sum-II-Input-Array-Is-Sorted]] +- [[Two pointers approach]] ##### Links: diff --git a/OJ notes/pages/Leetcode Remove-Nth-Node-From-End-of-List.md b/OJ notes/pages/Leetcode Remove-Nth-Node-From-End-of-List.md new file mode 100644 index 0000000..2527bfd --- /dev/null +++ b/OJ notes/pages/Leetcode Remove-Nth-Node-From-End-of-List.md @@ -0,0 +1,184 @@ +# 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; + } +}; +``` \ No newline at end of file