Skip to content

Commit 5fc0b58

Browse files
authored
Merge pull request #462 from TTWShell/feature/200-300-hard
Feature/200 300 hard
2 parents 332a9d4 + 613c3e8 commit 5fc0b58

File tree

5 files changed

+219
-0
lines changed

5 files changed

+219
-0
lines changed

leetcode/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,9 @@
185185
| 209 | [Minimum Size Subarray Sum](binary-search/minSubArrayLen.go) | [Medium][] |
186186
| 210 | [Course Schedule II](graph/findOrder.go) | [Medium][] |
187187
| 211 | [Add and Search Word - Data structure design](design/WordDictionary.go) | [Medium][] |
188+
| 212 | [Word Search II](trie/findWords.go) | [Hard][] |
188189
| 213 | [House Robber II](dynamic-programming/rob2.go) | [Medium][] |
190+
| 214 | [Shortest Palindrome](string/shortestPalindrome.go) | [Hard][] |
189191
| 215 | [Kth Largest Element in an Array](heap/findKthLargest.go) | [Medium][] |
190192
| 216 | [Combination Sum III](backtracking/combinationSum3.go) | [Medium][] |
191193
| 217 | [Contains Duplicate](hash-table/containsDuplicate.go) | [Easy][] |

leetcode/string/shortestPalindrome.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* https://leetcode.com/problems/shortest-palindrome/
2+
Given a string s, you are allowed to convert it to a palindrome by
3+
adding characters in front of it. Find and return the shortest
4+
palindrome you can find by performing this transformation.
5+
6+
Example 1:
7+
8+
Input: "aacecaaa"
9+
Output: "aaacecaaa"
10+
11+
Example 2:
12+
13+
Input: "abcd"
14+
Output: "dcbabcd"
15+
*/
16+
17+
package lstring
18+
19+
func shortestPalindrome(s string) string {
20+
isPalindrome := func(start, end int) bool {
21+
for i := start; i < start+(end-start)/2; i++ {
22+
if s[i] != s[end-1-i] {
23+
return false
24+
}
25+
}
26+
return true
27+
}
28+
29+
end := len(s)
30+
for ; end >= 1; end-- {
31+
if isPalindrome(0, end) {
32+
break
33+
}
34+
}
35+
36+
tmp, idx := make([]byte, len(s)-end), 0
37+
for i := len(s) - 1; i >= end; i-- {
38+
tmp[idx] = s[i]
39+
idx++
40+
}
41+
return string(tmp) + s
42+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package lstring
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Test_shortestPalindrome(t *testing.T) {
10+
assert := assert.New(t)
11+
12+
assert.Equal("abba", shortestPalindrome("abba"))
13+
assert.Equal("aaacecaaa", shortestPalindrome("aacecaaa"))
14+
assert.Equal("dcbabcd", shortestPalindrome("abcd"))
15+
}

leetcode/trie/findWords.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/* https://leetcode.com/problems/word-search-ii/
2+
Given a 2D board and a list of words from the dictionary, find all words in the board.
3+
4+
Each word must be constructed from letters of sequentially adjacent cell,
5+
where "adjacent" cells are those horizontally or vertically neighboring.
6+
The same letter cell may not be used more than once in a word.
7+
8+
Example:
9+
10+
Input:
11+
board = [
12+
['o','a','a','n'],
13+
['e','t','a','e'],
14+
['i','h','k','r'],
15+
['i','f','l','v']
16+
]
17+
words = ["oath","pea","eat","rain"]
18+
19+
Output: ["eat","oath"]
20+
21+
Note:
22+
23+
All inputs are consist of lowercase letters a-z.
24+
The values of words are distinct.
25+
*/
26+
27+
package ltrie
28+
29+
type ByteTrie struct {
30+
IsRoot bool
31+
Root string
32+
Next map[byte]*ByteTrie
33+
}
34+
35+
func ByteTrieConstructor(dict []string) ByteTrie {
36+
trie := &ByteTrie{IsRoot: false, Next: map[byte]*ByteTrie{}}
37+
for _, word := range dict {
38+
var (
39+
cur, end = trie, len(word)
40+
tmp *ByteTrie
41+
)
42+
for i := range word {
43+
c := word[i]
44+
if next, ok := cur.Next[c]; ok {
45+
cur = next
46+
} else {
47+
tmp = &ByteTrie{IsRoot: false, Next: map[byte]*ByteTrie{}}
48+
cur.Next[c] = tmp
49+
cur = tmp
50+
}
51+
}
52+
cur.Root = word[0:end]
53+
cur.IsRoot = true
54+
}
55+
return *trie
56+
}
57+
58+
func findWords(board [][]byte, words []string) []string {
59+
if len(board) == 0 {
60+
return []string{}
61+
}
62+
63+
trie := ByteTrieConstructor(words)
64+
65+
m, n := len(board), len(board[0])
66+
tmp := map[string]int{}
67+
var path map[[2]int]bool
68+
69+
var search func(i, j int, trie *ByteTrie)
70+
search = func(i, j int, trie *ByteTrie) {
71+
char := board[i][j]
72+
path[[2]int{i, j}] = true
73+
if subTrie, ok := trie.Next[char]; ok {
74+
if subTrie.IsRoot {
75+
tmp[subTrie.Root]++
76+
}
77+
for _, point := range [][2]int{{i - 1, j}, {i + 1, j}, {i, j - 1}, {i, j + 1}} {
78+
idxI, idxJ := point[0], point[1]
79+
if 0 <= idxI && idxI < m && 0 <= idxJ && idxJ < n && !path[[2]int{idxI, idxJ}] {
80+
search(idxI, idxJ, subTrie)
81+
}
82+
}
83+
}
84+
path[[2]int{i, j}] = false
85+
}
86+
87+
for i := 0; i < m; i++ {
88+
for j := 0; j < n; j++ {
89+
path = map[[2]int]bool{}
90+
search(i, j, &trie)
91+
}
92+
}
93+
94+
res := make([]string, 0, len(tmp))
95+
for word := range tmp {
96+
res = append(res, word)
97+
}
98+
return res
99+
}

leetcode/trie/findWords_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package ltrie
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Test_findWords(t *testing.T) {
10+
assert := assert.New(t)
11+
12+
assert.Equal([]string{}, findWords([][]byte{}, []string{"cdba"}))
13+
14+
board := [][]byte{
15+
{'o', 'a', 'a', 'n'},
16+
{'e', 't', 'a', 'e'},
17+
{'i', 'h', 'k', 'r'},
18+
{'i', 'f', 'l', 'v'},
19+
}
20+
excepted := []string{"eat", "oath"}
21+
result := findWords(board, []string{"oath", "pea", "eat", "rain"})
22+
assert.Subset(excepted, result)
23+
assert.Len(result, 2)
24+
25+
board = [][]byte{{'a', 'a'}}
26+
assert.Equal([]string{}, findWords(board, []string{"aaa"}))
27+
28+
board = [][]byte{{'a', 'b'}, {'c', 'd'}}
29+
assert.Equal([]string{"cdba"}, findWords(board, []string{"cdba"}))
30+
31+
board = [][]byte{
32+
{'b', 'a', 'a', 'b', 'a', 'b'},
33+
{'a', 'b', 'a', 'a', 'a', 'a'},
34+
{'a', 'b', 'a', 'a', 'a', 'b'},
35+
{'a', 'b', 'a', 'b', 'b', 'a'},
36+
{'a', 'a', 'b', 'b', 'a', 'b'},
37+
{'a', 'a', 'b', 'b', 'b', 'a'},
38+
{'a', 'a', 'b', 'a', 'a', 'b'},
39+
}
40+
words := []string{
41+
"aab", "bbaabaabaaaaabaababaaaaababb", "aabbaaabaaabaabaaaaaabbaaaba",
42+
"babaababbbbbbbaabaababaabaaa", "bbbaaabaabbaaababababbbbbaaa",
43+
"babbabbbbaabbabaaaaaabbbaaab", "bbbababbbbbbbababbabbbbbabaa",
44+
"babababbababaabbbbabbbbabbba", "abbbbbbaabaaabaaababaabbabba",
45+
"aabaabababbbbbbababbbababbaa", "aabbbbabbaababaaaabababbaaba",
46+
"ababaababaaabbabbaabbaabbaba", "abaabbbaaaaababbbaaaaabbbaab",
47+
"aabbabaabaabbabababaaabbbaab", "baaabaaaabbabaaabaabababaaaa",
48+
"aaabbabaaaababbabbaabbaabbaa", "aaabaaaaabaabbabaabbbbaabaaa",
49+
"abbaabbaaaabbaababababbaabbb", "baabaababbbbaaaabaaabbababbb",
50+
"aabaababbaababbaaabaabababab", "abbaaabbaabaabaabbbbaabbbbbb",
51+
"aaababaabbaaabbbaaabbabbabab", "bbababbbabbbbabbbbabbbbbabaa",
52+
"abbbaabbbaaababbbababbababba", "bbbbbbbabbbababbabaabababaab",
53+
"aaaababaabbbbabaaaaabaaaaabb", "bbaaabbbbabbaaabbaabbabbaaba",
54+
"aabaabbbbaabaabbabaabababaaa", "abbababbbaababaabbababababbb",
55+
"aabbbabbaaaababbbbabbababbbb", "babbbaabababbbbbbbbbaabbabaa",
56+
}
57+
result = findWords(board, words)
58+
excepted = []string{"aab", "aabbbbabbaababaaaabababbaaba", "abaabbbaaaaababbbaaaaabbbaab", "ababaababaaabbabbaabbaabbaba"}
59+
assert.Subset(excepted, result)
60+
assert.Len(result, 4)
61+
}

0 commit comments

Comments
 (0)