Skip to content

Commit 646a2f3

Browse files
authored
Merge pull request neetcode-gh#766 from Raven1233/main
Added 211-Design-Add-And-Search-Words-Data-Structure.kt and 212-Words-Search-II.kt
2 parents ced8663 + 5d59465 commit 646a2f3

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class WordDictionary() {
2+
data class TrieNode(var isLeaf: Boolean = false, val children: MutableMap<Char, TrieNode> = mutableMapOf())
3+
4+
val root = TrieNode()
5+
6+
fun addWord(word: String) {
7+
var current = root
8+
for (c in word) {
9+
current = current.children.getOrPut(c) { TrieNode() }
10+
}
11+
current.isLeaf = true
12+
}
13+
14+
fun search(word: String): Boolean {
15+
var candidates = listOf(root)
16+
for (c in word) {
17+
candidates = when (c) {
18+
'.' -> candidates.flatMap { it.children.values }
19+
else -> candidates.mapNotNull { it.children[c] }
20+
}
21+
if (candidates.isEmpty()) return false
22+
}
23+
return candidates.any { it.isLeaf }
24+
}
25+
}

kotlin/212-Word-Search-II.kt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
class Solution {
2+
private companion object{
3+
const val IMPOSSIBLE: Char = '#'
4+
val DIRS = intArrayOf(0, -1, 0, 1, 0)
5+
}
6+
7+
fun findWords(board: Array<CharArray>, words: Array<String>): List<String> {
8+
val nRows = board.size
9+
val nCols = board[0].size
10+
val root = buildTrie(words)
11+
val ans = mutableListOf<String>()
12+
for(row in 0 until nRows){
13+
for(col in 0 until nCols){
14+
backtrack(row, col, board, root, ans)
15+
}
16+
}
17+
return ans
18+
}
19+
20+
private fun backtrack(row: Int, col: Int, board: Array<CharArray>, node: TrieNode, res: MutableList<String>){
21+
val nRows = board.size
22+
val nCols = board[0].size
23+
24+
if(row < 0 || row >= nRows || col < 0 || col >= nCols)
25+
return
26+
27+
val hold = board[row][col]
28+
val idx = hold.toInt() - 'a'.toInt();
29+
if(hold == IMPOSSIBLE || node.children[idx] == null){
30+
return
31+
}
32+
33+
var cur: TrieNode? = node
34+
cur = cur!!.children[idx]
35+
if(cur!!.word != null){
36+
res.add(cur.word!!)
37+
cur.word = null
38+
}
39+
40+
board[row][col] = IMPOSSIBLE
41+
for(d in 0 until 4){
42+
val r = row + DIRS[d]
43+
val c = col + DIRS[d + 1]
44+
backtrack(r, c, board, cur, res)
45+
}
46+
board[row][col] = hold
47+
}
48+
49+
private fun buildTrie(words: Array<String>): TrieNode{
50+
val root = TrieNode()
51+
for(word in words){
52+
var cur: TrieNode? = root
53+
for(ch in word){
54+
val idx = ch.toInt() - 'a'.toInt()
55+
if(cur!!.children[idx] == null)
56+
cur.children[idx] = TrieNode()
57+
58+
cur = cur.children[idx]
59+
}
60+
cur!!.word = word
61+
}
62+
return root
63+
}
64+
65+
private data class TrieNode(var word: String? = null){
66+
val children: Array<TrieNode?> = Array(26){ null }
67+
}
68+
}

0 commit comments

Comments
 (0)