1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| import java.util.*
class Node( var isEnd: Boolean = false, val next: Array<Node?> = Array(26) { null } )
class Trie { val root = Node()
fun insert(word: String) { var p = root for (c in word) { val i = c - 'a' if (p.next[i] == null) { p.next[i] = Node() } p = p.next[i]!! } p.isEnd = true } }
class Solution { private val deltaRow = intArrayOf(-1, 0, 1, 0) private val deltaColumn = intArrayOf(0, 1, 0, -1)
fun findWords(board: Array<CharArray>, words: Array<String>): List<String> { val trie = Trie() for (word in words) { trie.insert(word) } val result = HashSet<String>() val rows = board.size val columns = board[0].size val visited = Array(rows) { BooleanArray(columns) { false } } val path = Stack<Char>() for (row in 0 until rows) { for (column in 0 until columns) { backtrack(board, row, column, visited, trie.root, path, result) } } return result.toList() }
private fun backtrack( board: Array<CharArray>, row: Int, column: Int, visited: Array<BooleanArray>, node: Node, path: Stack<Char>, result: HashSet<String> ) { val c = board[row][column] val currentNode = node.next[c - 'a'] if (currentNode != null) { path.push(c) visited[row][column] = true if (currentNode.isEnd) { val sb = StringBuilder() for (i in path.indices) { sb.append(path[i]) } result.add(sb.toString()) } for (direction in 0..3) { val newRow = row + deltaRow[direction] val newColumn = column + deltaColumn[direction] val rows = board.size val columns = board[0].size val isInBound = newRow in 0 until rows && newColumn in 0 until columns if (isInBound && !visited[newRow][newColumn]) { backtrack(board, newRow, newColumn, visited, currentNode, path, result) } } path.pop() visited[row][column] = false } } }
|