-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path25.ReverseKGroup.cs
145 lines (125 loc) · 4.79 KB
/
25.ReverseKGroup.cs
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
// 25. Reverse Nodes in k-Group
// Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list.
// k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should remain as it is.
// You may not alter the values in the list's nodes, only nodes themselves may be changed.
// Example 1:
// Input: head = [1,2,3,4,5], k = 2
// Output: [2,1,4,3,5]
// Example 2:
// Input: head = [1,2,3,4,5], k = 3
// Output: [3,2,1,4,5]
// Constraints:
// The number of nodes in the list is n.
// 1 <= k <= n <= 5000
// 0 <= Node.val <= 1000
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
// Approch 1
public class Solution {
// Function to reverse every k nodes in a linked list
public ListNode ReverseKGroup(ListNode head, int k) {
// If the head is null or k is 1, no reversal is required
if (head == null || k == 1) {
return head;
}
// Create a dummy node to handle edge cases more easily
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prevGroupEnd = dummy;
while (true) {
// Check if there are at least k nodes left to reverse
ListNode kthNode = GetKthNode(prevGroupEnd, k);
if (kthNode == null) {
break;
}
// Reverse k nodes
ListNode nextGroupStart = kthNode.next;
ListNode[] reversedNodes = Reverse(prevGroupEnd.next, kthNode);
// Connect the previous group's end to the newly reversed group
ListNode temp = prevGroupEnd.next;
prevGroupEnd.next = reversedNodes[0];
reversedNodes[1].next = nextGroupStart;
// Move prevGroupEnd to the end of the reversed segment
prevGroupEnd = temp;
}
// Return the next of the dummy node, which will be the head of the reversed list
return dummy.next;
}
// Helper function to get the k-th node from the given node
private ListNode GetKthNode(ListNode start, int k) {
ListNode current = start;
for (int i = 0; i < k; i++) {
if (current == null) {
return null;
}
current = current.next;
}
return current;
}
// Helper function to reverse the nodes between start and end (inclusive)
private ListNode[] Reverse(ListNode start, ListNode end) {
ListNode prev = end.next;
ListNode curr = start;
while (prev != end) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return new ListNode[] { end, start };
}
}
//Approch 2
public class Solution {
// Function to reverse every k nodes in a linked list
public ListNode ReverseKGroup(ListNode head, int k) {
// If the head is null or k is 1, no reversal is required
if (head == null || k == 1)
return head;
// Create a dummy node to handle edge cases more easily
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
// Loop until prev becomes null, which means we have traversed the whole list
while (prev != null) {
// Reverse the next k nodes and update prev to the new tail of the reversed group
prev = ReverseNextK(prev, k);
}
// Return the next of the dummy node, which will be the head of the reversed list
return dummy.next;
}
// Function to reverse the next k nodes starting from prev
private ListNode ReverseNextK(ListNode prev, int k) {
// Initialize a pointer to find the end of the next k nodes
ListNode last = prev;
// Move last pointer k steps forward
for (int i = 0; i <= k; i++) {
last = last.next;
// If the remaining nodes are less than k, do not reverse
if (last == null && i != k)
return null;
}
// Initialize pointers for the reverse operation
ListNode tail = prev.next;
ListNode curr = prev.next.next;
// Reverse the next k nodes
while (curr != last) {
ListNode next = curr.next;
curr.next = prev.next;
prev.next = curr;
curr = next;
}
tail.next = next;
// Return the tail of the reversed group for the next iteration
return tail;
}
}