From db204325dfe148719e0c9b3f80e9b5dae6288c68 Mon Sep 17 00:00:00 2001 From: Vasko Zdravevski Date: Fri, 20 Dec 2019 11:38:24 -0700 Subject: [PATCH 1/2] day 396: longest palindromic subseq --- day396/problem.go | 67 ++++++++++++++++++++++++++++++++++++++++++ day396/problem_test.go | 48 ++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 day396/problem.go create mode 100644 day396/problem_test.go diff --git a/day396/problem.go b/day396/problem.go new file mode 100644 index 0000000..3e8bdb6 --- /dev/null +++ b/day396/problem.go @@ -0,0 +1,67 @@ +package day396 + +// LongestPalindromicSubsequenceBrute returns the Longest +// Palindromic Subsequence using brute force. +func LongestPalindromicSubsequenceBrute(str string) int { + runes := []rune(str) + + return lpsBrute(runes) +} + +func lpsBrute(r []rune) int { + switch l := len(r); { + case l == 1: + return 1 + case l == 2 && r[0] == r[1]: + return 2 + case r[0] == r[l-1]: + return lpsBrute(r[1:l-1]) + 2 + default: + return max( + lpsBrute(r[:l-1]), + lpsBrute(r[1:l]), + ) + } +} + +func max(a, b int) int { + if a > b { + return a + } + + return b +} + +// LongestPalindromicSubsequenceDP returns the Longest +// Palindromic Subsequence using Dynamic Programming. +// Runs in O(N^2) space and time. +func LongestPalindromicSubsequenceDP(str string) int { + runes := []rune(str) + + return lpsDP(runes) +} + +func lpsDP(r []rune) int { + n := len(r) + subprob := make([][]int, n) + + for i := range subprob { + subprob[i] = make([]int, n) + subprob[i][i] = 1 + } + + for length := 2; length <= n; length++ { + for i := 0; i <= n-length; i++ { + switch j := i + length - 1; { + case r[i] == r[j] && length == 2: + subprob[i][j] = 2 + case r[i] == r[j]: + subprob[i][j] = subprob[i+1][j-1] + 2 + default: + subprob[i][j] = max(subprob[i][j-1], subprob[i+1][j]) + } + } + } + + return subprob[0][n-1] +} diff --git a/day396/problem_test.go b/day396/problem_test.go new file mode 100644 index 0000000..8ca7992 --- /dev/null +++ b/day396/problem_test.go @@ -0,0 +1,48 @@ +package day396 + +import "testing" + +// nolint +var testcases = []struct { + str string + expected int +}{ + {"MAPTPTMTPA", 7}, + {"ABFOOBARRABOOFYZ", 12}, +} + +func TestLongestPalindromicSubsequenceBrute(t *testing.T) { + t.Parallel() + + for _, tc := range testcases { + if res := LongestPalindromicSubsequenceBrute(tc.str); res != tc.expected { + t.Errorf("Expected %v, got %v", tc.expected, res) + } + } +} + +func BenchmarkLongestPalindromicSubsequenceBrute(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, tc := range testcases { + LongestPalindromicSubsequenceBrute(tc.str) + } + } +} + +func TestLongestPalindromicSubsequenceDP(t *testing.T) { + t.Parallel() + + for _, tc := range testcases { + if res := LongestPalindromicSubsequenceDP(tc.str); res != tc.expected { + t.Errorf("Expected %v, got %v", tc.expected, res) + } + } +} + +func BenchmarkLongestPalindromicSubsequenceDP(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, tc := range testcases { + LongestPalindromicSubsequenceDP(tc.str) + } + } +} From b2f9d36488a6789f2ed509cdacd97f09f8452923 Mon Sep 17 00:00:00 2001 From: Vasko Zdravevski Date: Fri, 20 Dec 2019 11:39:31 -0700 Subject: [PATCH 2/2] add day 396 to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5b3d870..3fe325e 100644 --- a/README.md +++ b/README.md @@ -388,4 +388,5 @@ problems from * [Day 393](https://github.com/vaskoz/dailycodingproblem-go/issues/789) * [Day 394](https://github.com/vaskoz/dailycodingproblem-go/issues/791) * [Day 395](https://github.com/vaskoz/dailycodingproblem-go/issues/793) +* [Day 396](https://github.com/vaskoz/dailycodingproblem-go/issues/795)