Skip to content

Commit 8d653e6

Browse files
committed
Reverse Nodes in k-Group
1 parent 6ad2df7 commit 8d653e6

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// 25. Reverse Nodes in k-Group
2+
// Topics: 'Linked List', 'Recursion'
3+
// Level: 'Hard'
4+
5+
// Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list.
6+
7+
// 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.
8+
9+
// You may not alter the values in the list's nodes, only nodes themselves may be changed.
10+
11+
// Example 1:
12+
13+
// Input: head = [1,2,3,4,5], k = 2
14+
// Output: [2,1,4,3,5]
15+
16+
// Example 2:
17+
18+
// Input: head = [1,2,3,4,5], k = 3
19+
// Output: [3,2,1,4,5]
20+
21+
// Constraints:
22+
23+
// The number of nodes in the list is n.
24+
// 1 <= k <= n <= 5000
25+
// 0 <= Node.val <= 1000
26+
27+
// Follow-up: Can you solve the problem in O(1) extra memory space?
28+
29+
package reversenodeinkgroup
30+
31+
type ListNode struct {
32+
Next *ListNode
33+
Val int
34+
}
35+
36+
func reverseKGroup(head *ListNode, k int) *ListNode {
37+
dummy := &ListNode{}
38+
cur := head
39+
dcur := dummy
40+
for cur != nil {
41+
dcur.Next, dcur, cur = reverse(cur, k)
42+
}
43+
return dummy.Next
44+
}
45+
46+
func reverse(head *ListNode, k int) (*ListNode, *ListNode, *ListNode) {
47+
check := head
48+
i := k
49+
for check != nil && i > 1 {
50+
check = check.Next
51+
i--
52+
}
53+
if check == nil {
54+
return head, nil, nil
55+
}
56+
var prev *ListNode
57+
cur := head
58+
for k > 0 && cur != nil {
59+
next := cur.Next
60+
cur.Next = prev
61+
prev = cur
62+
cur = next
63+
k--
64+
}
65+
return prev, head, cur
66+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package reversenodeinkgroup
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
// Helper: convert slice to linked list
9+
func sliceToList(nums []int) *ListNode {
10+
dummy := &ListNode{}
11+
cur := dummy
12+
for _, n := range nums {
13+
cur.Next = &ListNode{Val: n}
14+
cur = cur.Next
15+
}
16+
return dummy.Next
17+
}
18+
19+
// Helper: convert linked list to slice
20+
func listToSlice(head *ListNode) []int {
21+
var result []int
22+
for head != nil {
23+
result = append(result, head.Val)
24+
head = head.Next
25+
}
26+
return result
27+
}
28+
29+
func TestReverseKGroup(t *testing.T) {
30+
tests := []struct {
31+
input []int
32+
k int
33+
want []int
34+
}{
35+
// Full reversal
36+
{[]int{1, 2, 3, 4, 5, 6}, 3, []int{3, 2, 1, 6, 5, 4}},
37+
// Last group less than k
38+
{[]int{1, 2, 3, 4, 5}, 3, []int{3, 2, 1, 4, 5}},
39+
// k = 1, list unchanged
40+
{[]int{1, 2, 3, 4}, 1, []int{1, 2, 3, 4}},
41+
// k = list length, whole list reversed
42+
{[]int{1, 2, 3, 4}, 4, []int{4, 3, 2, 1}},
43+
// k > list length, list unchanged
44+
{[]int{1, 2, 3}, 5, []int{1, 2, 3}},
45+
// Single element
46+
{[]int{1}, 2, []int{1}},
47+
}
48+
49+
for _, tt := range tests {
50+
t.Run("", func(t *testing.T) {
51+
head := sliceToList(tt.input)
52+
got := reverseKGroup(head, tt.k)
53+
gotSlice := listToSlice(got)
54+
if !reflect.DeepEqual(gotSlice, tt.want) {
55+
t.Errorf("reverseKGroup(%v, %d) = %v; want %v", tt.input, tt.k, gotSlice, tt.want)
56+
}
57+
})
58+
}
59+
}

0 commit comments

Comments
 (0)