-
Notifications
You must be signed in to change notification settings - Fork 0
/
remove_nth_node_from_end_of_list.cpp
152 lines (134 loc) · 4.4 KB
/
remove_nth_node_from_end_of_list.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* Problem: https://leetcode.com/problems/remove-nth-node-from-end-of-list/
Statement: Given the head of a linked list, remove the nth node from the end of the list and return its head.
Date: March 05, 2023\
Approach: Two pointers (a fast one and a slow one).
If we maintain a difference of n nodes between the two pointers,
then as fast pointer reaches the end of the linked list (i.e. null), the slow pointer would be at the target node.
Time complexity: O(n) (Single iteration over the linked list)
Space complexity: O(1) (No additional space)
*/
#include <bits/stdc++.h>
#include <lest.hpp>
using namespace std;
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) {
// Initialize the slow and fast pointer:
// fast pointer should be n nodes ahead of slow pointer.
ListNode* slowNode = head;
ListNode* fastNode = head;
int i = 0;
while (i < n)
{
fastNode = fastNode->next;
++i;
}
/*
Case: n = length of linked list
In this special case, positions of the slow and fast pointers:
- slow pointer: head of the linked list
- fast pointer: end of the linked list (i.e. null)
Hence slow pointer is at the target node.
Thus we need to make its next node as the head of the linked list and remove the target node.
*/
if (fastNode == nullptr)
{
ListNode* tempNode = head;
head = head->next;
delete tempNode;
return head;
}
/* As fastNode reaches end of the list, slowNode would be the nth node from the end of the list.
As we remove the target node, we need to ensure that its previous node is linked to target node's next node,
so that the linked list chain is maintained.
To achieve this, we stop the slow pointer at the target node's previous node.
*/
while (fastNode->next != nullptr)
{
// Move both the pointers one step
fastNode = fastNode->next;
slowNode = slowNode->next;
}
ListNode* tempNode = slowNode->next;
slowNode->next = slowNode->next->next;
delete tempNode;
return head;
}
};
ListNode* create_linked_list(vector<int> vec)
{
ListNode* head = nullptr;
ListNode* prevNode = nullptr;
for (auto it=vec.begin(); it != vec.end(); ++it)
{
ListNode* node = new ListNode(*it);
if (it == vec.begin())
{
head = node;
}
else
{
prevNode->next = node;
}
// Update prevNode to the current node for the next iteration
prevNode = node;
}
return head;
}
vector<int> create_vector(ListNode* head)
{
vector<int> vec;
ListNode* node = head;
while (node)
{
vec.push_back(node->val);
node = node->next;
}
return vec;
}
lest::test tests[] = {
CASE("Test Case #1"){
vector<int> vec = {1,2,3,4,5};
ListNode* head = create_linked_list(vec);
int n = 2;
vector<int> vec_post_removal = {1,2,3,5};
Solution sln;
EXPECT(create_vector(sln.removeNthFromEnd(head, n)) == vec_post_removal);
},
CASE("Test Case #2"){
vector<int> vec = {1,2,3,4,5};
ListNode* head = create_linked_list(vec);
int n = 1;
vector<int> vec_post_removal = {1,2,3,4};
Solution sln;
EXPECT(create_vector(sln.removeNthFromEnd(head, n)) == vec_post_removal);
},
CASE("Test Case #3"){
vector<int> vec = {1,2,3,4,5};
ListNode* head = create_linked_list(vec);
int n = 5;
vector<int> vec_post_removal = {2,3,4,5};
Solution sln;
EXPECT(create_vector(sln.removeNthFromEnd(head, n)) == vec_post_removal);
},
CASE("Test Case #4"){
vector<int> vec = {1};
ListNode* head = create_linked_list(vec);
int n = 1;
vector<int> vec_post_removal = {};
Solution sln;
EXPECT(create_vector(sln.removeNthFromEnd(head, n)) == vec_post_removal);
},
};
int main(int argc, char** argv)
{
lest::run(tests, argc, argv);
}