Skip to content

Commit ef153ef

Browse files
committed
25 Reverse Nodes in k-Group
1 parent 0c66ca6 commit ef153ef

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
+ [22 Generate Parentheses(递归、搜索)](algorithms/GenerateParentheses)
2020
+ [23 Merge k Sorted Lists(堆)](algorithms/MergekSortedLists)
2121
+ [24 Swap Nodes in Pairs(链表操作)](algorithms/SwapNodesinPairs)
22+
+ [25 Reverse Nodes in k-Group(链表操作)](algorithms/ReverseNodesink-Group)
2223
+ [26 Remove Duplicates from Sorted Array](algorithms/RemoveDuplicatesfromSortedArray)
2324
+ [27 Remove Element](algorithms/RemoveElement)
2425
+ [29 Divide Two Integers(位运算、最小负数绝对值、溢出检测)](algorithms/DivideTwoIntegers)
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
## Reverse Nodes in k-Group
2+
3+
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
4+
5+
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
6+
7+
You may not alter the values in the nodes, only nodes itself may be changed.
8+
9+
Only constant memory is allowed.
10+
11+
For example,
12+
13+
```
14+
Given this linked list: 1->2->3->4->5
15+
16+
For k = 2, you should return: 2->1->4->3->5
17+
18+
For k = 3, you should return: 3->2->1->4->5
19+
```
20+
21+
## Solution
22+
23+
首先定义一个reverse函数,接收两个指针,分别为begin和end,表示reverse的开始和结束,同时由于end的next指针会丢失,因此应该预先保存并返回
24+
25+
```cpp
26+
ListNode *reverse(ListNode *begin, ListNode *end) {
27+
assert(begin && end);
28+
ListNode *p = begin;
29+
ListNode *prev = nullptr;
30+
ListNode *endFlag = end->next;
31+
while (p != endFlag) { // 条件不能写成 p != end->next, 因为end->next reverse时会修改
32+
ListNode *q = p->next; // 保存next指针
33+
p->next = prev;
34+
prev = p;
35+
p = q;
36+
}
37+
return p;
38+
}
39+
```
40+
41+
然后分组,思路是每次走k步,找到需要reverse的开始和结束节点,同时注意保存之前已经处理好的尾部节点prev
42+
43+
```cpp
44+
while (begin) {
45+
int K = k - 1; // 包括begin节点,因此后面还需要k-1个节点
46+
ListNode *p = begin;
47+
while (K && p->next) {
48+
end = p->next;
49+
p = p->next;
50+
K--;
51+
}
52+
if (K) { // 不足k,不需要reverse,但注意需要更新尾部节点
53+
prev->next = begin; // 记得最后更新prev指针
54+
return head;
55+
}
56+
ListNode *next = reverse(begin, end);
57+
prev->next = end; // 更新已经处理完毕的尾部节点
58+
prev = begin; // 更新处理完毕的尾部节点指针
59+
begin = next; // begin从下一个节点开始
60+
}
61+
```
62+
63+
完整代码:
64+
65+
```cpp
66+
ListNode *reverseKGroup(ListNode *head, int k) {
67+
if (head == nullptr || k <= 1)
68+
return head;
69+
ListNode *begin = head, *end = nullptr;
70+
ListNode *prev = nullptr;
71+
/* First reverse */
72+
if (begin) { // 第一次操作,需要更新head和prev指针
73+
int K = k - 1;
74+
ListNode *p = begin;
75+
while (K && p->next) {
76+
end = p->next;
77+
p = p->next;
78+
K--;
79+
}
80+
if (K)
81+
return head;
82+
ListNode *next = reverse(begin, end);
83+
prev = begin;
84+
head = end;
85+
begin = next;
86+
}
87+
while (begin) {
88+
int K = k - 1;
89+
ListNode *p = begin;
90+
while (K && p->next) {
91+
end = p->next;
92+
p = p->next;
93+
K--;
94+
}
95+
if (K) {
96+
prev->next = begin; // 记得最后更新prev指针
97+
return head;
98+
}
99+
ListNode *next = reverse(begin, end);
100+
prev->next = end;
101+
prev = begin;
102+
begin = next;
103+
}
104+
return head;
105+
}
106+
```
107+
108+
## 得瑟
109+
110+
居然一次AC,:)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include <iostream>
2+
#include <cstdio>
3+
#include <vector>
4+
#include <algorithm>
5+
#include <string>
6+
using namespace std;
7+
#include <stdlib.h>
8+
#include <cassert>
9+
struct ListNode {
10+
int val;
11+
ListNode *next;
12+
ListNode(int x): val(x), next(nullptr) {}
13+
};
14+
class Solution {
15+
public:
16+
ListNode *reverseKGroup(ListNode *head, int k) {
17+
if (head == nullptr || k <= 1)
18+
return head;
19+
ListNode *begin = head, *end = nullptr;
20+
ListNode *prev = nullptr;
21+
/* First reverse */
22+
/* 第一次操作,主要需要更新head和prev指针 */
23+
if (begin) {
24+
int K = k - 1;
25+
ListNode *p = begin;
26+
while (K && p->next) {
27+
end = p->next;
28+
p = p->next;
29+
K--;
30+
}
31+
if (K)
32+
return head;
33+
ListNode *next = reverse(begin, end);
34+
prev = begin;
35+
head = end;
36+
begin = next;
37+
}
38+
while (begin) {
39+
int K = k - 1;
40+
ListNode *p = begin;
41+
while (K && p->next) {
42+
end = p->next;
43+
p = p->next;
44+
K--;
45+
}
46+
if (K) { // 不足k个节点,不需要reverse,但需要更新处理完毕的尾部节点
47+
prev->next = begin; // 记得最后更新prev指针
48+
return head;
49+
}
50+
ListNode *next = reverse(begin, end);
51+
prev->next = end;
52+
prev = begin;
53+
begin = next;
54+
}
55+
return head;
56+
}
57+
private:
58+
ListNode *reverse(ListNode *begin, ListNode *end) {
59+
assert(begin && end);
60+
ListNode *p = begin;
61+
ListNode *prev = nullptr;
62+
ListNode *endFlag = end->next;
63+
while (p != endFlag) { // 条件不能写成 p != end->next, 因为end->next reverse时会修改
64+
ListNode *q = p->next;
65+
p->next = prev;
66+
prev = p;
67+
p = q;
68+
}
69+
return p;
70+
}
71+
72+
};
73+
int getLength(ListNode *head)
74+
{
75+
int len = 0;
76+
ListNode *p = head;
77+
while (p) {
78+
++len;
79+
p = p->next;
80+
}
81+
return len;
82+
}
83+
void print(ListNode *head)
84+
{
85+
if (head == nullptr) {
86+
printf("NULL\n");
87+
return;
88+
}
89+
struct ListNode *p = head;
90+
while (p) {
91+
printf("%d ", p->val);
92+
p = p->next;
93+
}
94+
printf("\n");
95+
}
96+
ListNode * mk_list(ListNode **ha, int a[], int n)
97+
{
98+
if (n < 1)
99+
return nullptr;
100+
ListNode *p = new ListNode(a[0]);
101+
*ha = p;
102+
for (int i = 1; i < n; ++i) {
103+
ListNode *q = new ListNode(a[i]);
104+
p->next = q;
105+
p = q;
106+
}
107+
return p;
108+
}
109+
void free_list(struct ListNode *head)
110+
{
111+
struct ListNode *p = head;
112+
while (p) {
113+
struct ListNode *q = p->next;
114+
delete p;
115+
p = q;
116+
}
117+
}
118+
int main(int argc, char **argv)
119+
{
120+
Solution solution;
121+
struct ListNode *head = NULL;
122+
int a[] = {1, 2, 3, 4, 5, 6};
123+
mk_list(&head, a, 6);
124+
print(head);
125+
head = solution.reverseKGroup(head, 3);
126+
print(head);
127+
return 0;
128+
}

0 commit comments

Comments
 (0)