Skip to content

Commit 910a34e

Browse files
committed
Remove nth node from end of list
1 parent e7cf613 commit 910a34e

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// 19. Remove nth node from end of list
2+
// Topics: 'Two Pointers', 'Linked List'
3+
// Level: 'Medium'
4+
5+
// Given the head of a linked list, remove the nth node from the end of the list and return its head.
6+
7+
// Example 1:
8+
9+
// Input: head = [1,2,3,4,5], n = 2
10+
// Output: [1,2,3,5]
11+
12+
// Example 2:
13+
14+
// Input: head = [1], n = 1
15+
// Output: []
16+
17+
// Example 3:
18+
19+
// Input: head = [1,2], n = 1
20+
// Output: [1]
21+
22+
// Constraints:
23+
24+
// The number of nodes in the list is sz.
25+
// 1 <= sz <= 30
26+
// 0 <= Node.val <= 100
27+
// 1 <= n <= sz
28+
29+
package removenthnodefromendoflist
30+
31+
func removeNthFromEnd(head *ListNode, n int) *ListNode {
32+
dummy := &ListNode{Next: head}
33+
34+
l := dummy
35+
r := head
36+
for n > 0 {
37+
r = r.Next
38+
n--
39+
}
40+
for r != nil {
41+
r = r.Next
42+
l = l.Next
43+
}
44+
l.Next = l.Next.Next
45+
46+
return dummy.Next
47+
}
48+
49+
type ListNode struct {
50+
Val int
51+
Next *ListNode
52+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package removenthnodefromendoflist
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestRemoveNthFromEnd(t *testing.T) {
9+
tests := []struct {
10+
name string
11+
head *ListNode
12+
n int
13+
want *ListNode
14+
}{
15+
{
16+
name: "remove 2nd from end in 5-node list",
17+
head: createList([]int{1, 2, 3, 4, 5}),
18+
n: 2,
19+
want: createList([]int{1, 2, 3, 5}),
20+
},
21+
{
22+
name: "remove only node",
23+
head: createList([]int{1}),
24+
n: 1,
25+
want: nil,
26+
},
27+
{
28+
name: "remove last node in 2-node list",
29+
head: createList([]int{1, 2}),
30+
n: 1,
31+
want: createList([]int{1}),
32+
},
33+
{
34+
name: "remove first node in 2-node list",
35+
head: createList([]int{1, 2}),
36+
n: 2,
37+
want: createList([]int{2}),
38+
},
39+
{
40+
name: "remove last node in long list",
41+
head: createList([]int{1, 2, 3, 4, 5, 6}),
42+
n: 1,
43+
want: createList([]int{1, 2, 3, 4, 5}),
44+
},
45+
{
46+
name: "remove first node in long list",
47+
head: createList([]int{1, 2, 3, 4, 5}),
48+
n: 5,
49+
want: createList([]int{2, 3, 4, 5}),
50+
},
51+
{
52+
name: "remove middle node 2",
53+
head: createList([]int{1, 2, 3, 4, 5}),
54+
n: 4,
55+
want: createList([]int{1, 3, 4, 5}),
56+
},
57+
{
58+
name: "remove middle node 3",
59+
head: createList([]int{1, 2, 3, 4, 5}),
60+
n: 3,
61+
want: createList([]int{1, 2, 4, 5}),
62+
},
63+
}
64+
65+
for _, tt := range tests {
66+
t.Run(tt.name, func(t *testing.T) {
67+
got := removeNthFromEnd(tt.head, tt.n)
68+
if !equalLists(got, tt.want) {
69+
t.Errorf("removeNthFromEnd() = %v, want %v", listToSlice(got), listToSlice(tt.want))
70+
}
71+
})
72+
}
73+
}
74+
75+
func createList(vals []int) *ListNode {
76+
if len(vals) == 0 {
77+
return nil
78+
}
79+
head := &ListNode{Val: vals[0]}
80+
current := head
81+
for i := 1; i < len(vals); i++ {
82+
current.Next = &ListNode{Val: vals[i]}
83+
current = current.Next
84+
}
85+
return head
86+
}
87+
88+
func listToSlice(head *ListNode) []int {
89+
var result []int
90+
for head != nil {
91+
result = append(result, head.Val)
92+
head = head.Next
93+
}
94+
return result
95+
}
96+
97+
func equalLists(l1, l2 *ListNode) bool {
98+
return reflect.DeepEqual(listToSlice(l1), listToSlice(l2))
99+
}

0 commit comments

Comments
 (0)