class Trie { private static class Node { boolean end = false; Node[] son = new Node[26]; } Node root; public Trie() { root = new Node(); } public void insert(String word) { Node cur = root; for (char c : word.toCharArray()) { int i = c - 'a'; if (cur.son[i] == null) { cur.son[i] = new Node(); } //进入下一层 cur = cur.son[i]; } //字符串树最后一层 cur.end = true; } public boolean search(String word) { return find(word) == 2; } public boolean startsWith(String prefix) { return find(prefix) != 0; } int find(String word) { Node cur = root; //遍历二十六叉树 for (char c : word.toCharArray()) { int i = c - 'a'; if (cur.son[i] == null) { return 0; } cur = cur.son[i]; } // 走过同样的路(2=完全匹配,1=前缀匹配) return cur.end ? 2 : 1; }}
输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]输出:["eat","oath"]
思路:字典树+回溯算法
class Solution { List<String> res = new ArrayList<>(); boolean[][] visited; int m, n; Node root = new Node(); public List<String> findWords(char[][] board, String[] words) { m = board.length; n = board[0].length; visited = new boolean[m][n]; for (String w : words) { insert(w); } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { dfs(board, i, j, root, ""); } } return res; } void dfs(char[][] board, int i, int j, Node node, String path) { if (i < 0 || j < 0 || i >= m || j >= n) { return; } if (visited[i][j]) { return; } char c = board[i][j]; if (node.son[c - 'a'] == null) return; visited[i][j] = true; node = node.son[c - 'a']; path += c; if (node.end) { res.add(path); node.end = false; } dfs(board, i + 1, j, node, path); dfs(board, i - 1, j, node, path); dfs(board, i, j + 1, node, path); dfs(board, i, j - 1, node, path); visited[i][j] = false; } public void insert(String word) { Node cur = root; for (char c : word.toCharArray()) { int i = c - 'a'; if (cur.son[i] == null) { cur.son[i] = new Node(); } cur = cur.son[i]; } cur.end = true; } static class Node { boolean end = false; Node[] son = new Node[26]; }}