From d7d23a28c87dadd26f041457469f81cc0e322142 Mon Sep 17 00:00:00 2001 From: Vasko Zdravevski Date: Fri, 8 Feb 2019 17:39:09 -0700 Subject: [PATCH 1/2] day 169: mergesort a singly linked list in O(N log N) time and O(1) space --- day169/problem.go | 60 ++++++++++++++++++++++++++++++++++++++++++ day169/problem_test.go | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 day169/problem.go create mode 100644 day169/problem_test.go diff --git a/day169/problem.go b/day169/problem.go new file mode 100644 index 0000000..16511bc --- /dev/null +++ b/day169/problem.go @@ -0,0 +1,60 @@ +package day169 + +// SinglyLL is a singly linked list of integers. +type SinglyLL struct { + Value int + Next *SinglyLL +} + +// MergesortSinglyLinkedList runs in O(N log N) time and O(1) space. +func MergesortSinglyLinkedList(head *SinglyLL) *SinglyLL { + var size int + ptr := head + for ptr != nil { + size++ + ptr = ptr.Next + } + if size == 1 { + return head + } + ptr = head + for i := 0; i < (size/2)-1; i++ { + ptr = ptr.Next + } + half := ptr.Next + ptr.Next = nil + a := MergesortSinglyLinkedList(head) + b := MergesortSinglyLinkedList(half) + return mergeSorted(a, b) +} + +func mergeSorted(a, b *SinglyLL) *SinglyLL { + result := &SinglyLL{} + ptr := result + for a != nil || b != nil { + if a != nil && b != nil { + if a.Value < b.Value { + ptr.Next = a + a = a.Next + ptr = ptr.Next + ptr.Next = nil + } else { + ptr.Next = b + b = b.Next + ptr = ptr.Next + ptr.Next = nil + } + } else if a != nil { + ptr.Next = a + a = a.Next + ptr = ptr.Next + ptr.Next = nil + } else if b != nil { + ptr.Next = b + b = b.Next + ptr = ptr.Next + ptr.Next = nil + } + } + return result.Next +} diff --git a/day169/problem_test.go b/day169/problem_test.go new file mode 100644 index 0000000..2d946a6 --- /dev/null +++ b/day169/problem_test.go @@ -0,0 +1,52 @@ +package day169 + +import "testing" + +var testcases = []struct { + input *SinglyLL + expected *SinglyLL +}{ + {&SinglyLL{4, &SinglyLL{1, &SinglyLL{-3, &SinglyLL{99, nil}}}}, + &SinglyLL{-3, &SinglyLL{1, &SinglyLL{4, &SinglyLL{99, nil}}}}}, +} + +func TestMergesortSinglyLinkedList(t *testing.T) { + t.Parallel() + for tcid, tc := range testcases { + input := copySinglyLL(tc.input) + if result := MergesortSinglyLinkedList(input); !equal(result, tc.expected) { + t.Errorf("Lists don't match for tcid%d", tcid) + } + } +} + +func BenchmarkMergesortSinglyLinkedList(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, tc := range testcases { + input := copySinglyLL(tc.input) + MergesortSinglyLinkedList(input) + } + } +} + +func copySinglyLL(a *SinglyLL) *SinglyLL { + result := &SinglyLL{} + ptr := result + for a != nil { + ptr.Next = &SinglyLL{a.Value, nil} + ptr = ptr.Next + a = a.Next + } + return result.Next +} + +func equal(a, b *SinglyLL) bool { + for a != nil && b != nil { + if a.Value != b.Value { + return false + } + a = a.Next + b = b.Next + } + return a == nil && b == nil +} From 7aa190a7873d13ef07790d9d10d0c0c2a9f26472 Mon Sep 17 00:00:00 2001 From: Vasko Zdravevski Date: Fri, 8 Feb 2019 17:39:51 -0700 Subject: [PATCH 2/2] add day 169 to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b2e55e4..84efb38 100644 --- a/README.md +++ b/README.md @@ -180,4 +180,5 @@ problems from * [Day 166](https://github.com/vaskoz/dailycodingproblem-go/issues/346) * [Day 167](https://github.com/vaskoz/dailycodingproblem-go/issues/347) * [Day 168](https://github.com/vaskoz/dailycodingproblem-go/issues/348) +* [Day 169](https://github.com/vaskoz/dailycodingproblem-go/issues/352) * [Day 170](https://github.com/vaskoz/dailycodingproblem-go/issues/353)