Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 13
Good morning! Here's your coding interview problem for today.

This problem was asked by Amazon.

Given an integer k and a string s, find the length of the longest substring that contains at most k distinct characters.

For example, given s = "abcba" and k = 2, the longest substring with k distinct characters is "bcb".



Pull request description:
day 13 solution
Resolves #29 

Patch:
diff --git a/README.md b/README.md
index f6e2e37..c2c490e 100644
--- a/README.md
+++ b/README.md
@@ -23,3 +23,4 @@ problems from
 * [Day 11](https://github.com/vaskoz/dailycodingproblem-go/issues/23)
 * [Day 12](https://github.com/vaskoz/dailycodingproblem-go/issues/25)
 * [Day 12 Count and Deepest](https://github.com/vaskoz/dailycodingproblem-go/issues/27)
+* [Day 13](https://github.com/vaskoz/dailycodingproblem-go/issues/29)
diff --git a/day13/problem.go b/day13/problem.go
new file mode 100644
index 0000000..2b0c251
--- /dev/null
+++ b/day13/problem.go
@@ -0,0 +1,33 @@
+package day13
+
+// LongestSubKDistinct returns  find the length of the longest substring
+// that contains at most k distinct characters.
+// Runs in O(N) time. Uses O(K) space for the map.
+func LongestSubKDistinct(s string, k int) string {
+	r := []rune(s)
+	if len(r) <= k {
+		return string(r)
+	}
+	letters := make(map[rune]int)
+	var curL, maxL, curR, maxR int
+	for curR < len(r) {
+		if _, found := letters[r[curR]]; len(letters) < k || found {
+			letters[r[curR]]++
+			curR++
+			if curR-curL > maxR-maxL {
+				maxL, maxR = curL, curR
+			}
+		} else {
+			for len(letters) >= k {
+				if count := letters[r[curL]]; count == 1 {
+					delete(letters, r[curL])
+				} else {
+					letters[r[curL]]--
+				}
+				curL++
+			}
+		}
+
+	}
+	return string(r[maxL:maxR])
+}


Test patch:
diff --git a/day13/problem_test.go b/day13/problem_test.go
new file mode 100644
index 0000000..2a6dbfc
--- /dev/null
+++ b/day13/problem_test.go
@@ -0,0 +1,31 @@
+package day13
+
+import "testing"
+
+var testcases = []struct {
+	input    string
+	k        int
+	expected string
+}{
+	{"abcba", 2, "bcb"},
+	{"aa", 2, "aa"},
+	{"xyzabababbbbaaaac", 2, "abababbbbaaaa"},
+	{"xyzabababbbbaaaac", 2, "abababbbbaaaa"},
+}
+
+func TestLongestSubKDistinct(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result := LongestSubKDistinct(tc.input, tc.k); result != tc.expected {
+			t.Errorf("Given %v I expected %v but got %v with k %v", tc.input, tc.expected, result, tc.k)
+		}
+	}
+}
+
+func BenchmarkLongestSubKDistinct(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			LongestSubKDistinct(tc.input, tc.k)
+		}
+	}
+}