-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreverse_nodes_in_k_group.cpp
More file actions
169 lines (154 loc) · 3.67 KB
/
reverse_nodes_in_k_group.cpp
File metadata and controls
169 lines (154 loc) · 3.67 KB
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
* =====================================================================================
*
* Filename: reverse_nodes_in_k_group.cpp
*
* Description: 25. Reverse Nodes in k-Group. Given a linked list, reverse the nodes
* of a linked list k at a time and return its modified list.
*
* Version: 1.0
* Created: 04/16/19 12:50:00
* Revision: none
* Compiler: gcc
*
* Author: Zhu Xianfeng (), xianfeng.zhu@gmail.com
* Organization:
*
* =====================================================================================
*/
#include <cstdio>
#include <cstdlib>
#include <vector>
struct ListNode {
int val;
ListNode* next;
ListNode(int x = 0, ListNode* n = nullptr) : val(x), next(n) {}
void printList() {
ListNode* ptr = this;
while (ptr != nullptr) {
printf("%d%s", ptr->val, (ptr->next != nullptr ? " -> " : "\n"));
ptr = ptr->next;
}
}
static ListNode* convert(const std::vector<int>& nums) {
ListNode dummy(0);
ListNode* ptr = &dummy;
for (const int val : nums) {
ptr->next = new ListNode(val);
ptr = ptr->next;
}
return dummy.next;
}
};
// Traverse once, min O(n), max O(n + k)
class Solution1 {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode dummy(0);
ListNode* first = &dummy;
ListNode* last = &dummy;
ListNode* ptr = head;
ListNode* tmp = nullptr;
int count = 0;
while (ptr != nullptr) {
tmp = ptr->next;
ptr->next = first->next;
first->next = ptr;
if (last->next != nullptr) {
last = last->next;
}
count++;
if ((count % k) == 0) {
first = last;
}
ptr = tmp;
}
// Reverse count < k
count %= k;
if (count > 0) {
ptr = first->next;
first->next = nullptr;
while (ptr != nullptr) {
tmp = ptr->next;
ptr->next = first->next;
first->next = ptr;
ptr = tmp;
}
}
return dummy.next;
}
};
// Traverse twice, O(2n), but more readable
class Solution2 {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode dummy(0);
ListNode* left = &dummy;
ListNode* right = &dummy;
ListNode* cur = head;
while (true) {
int count = 0;
while (cur != nullptr && count != k) {
cur = cur->next;
count++;
}
if (count != k) {
right->next = head;
break;
}
// Reverse current k-group
ListNode* tmp = nullptr;
left = right;
while (count-- > 0) {
tmp = head->next;
head->next = left->next;
left->next = head;
head = tmp;
if (right->next != nullptr) {
right = right->next;
}
}
}
return dummy.next;
}
};
// Recursion
class Solution3 {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
int count = 0;
ListNode* p = head;
while (p != nullptr) {
p = p->next;
if (++count >= k) {
break;
}
}
if (count < k) {
return head;
}
// Keep the rest list and reverse later
ListNode* rest = p;
// Reverse k nodes from head
ListNode dummy;
ListNode* tail = head;
while (count-- > 0) {
p = head->next;
head->next = dummy.next;
dummy.next = head;
head = p;
}
// Reverse the rest
tail->next = reverseKGroup(rest, k);
return dummy.next;
}
};
using Solution = Solution2;
int main(int argc, char* argv[]) {
const std::vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
ListNode* head = ListNode::convert(nums);
head->printList();
head = Solution().reverseKGroup(head, 3);
head->printList();
return 0;
}