LeetCode第212题单词搜索 II
题目:
给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例 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"]
示例 2:
输入:board = [["a","b"],["c","d"]], words = ["abcb"] 输出:[]
提示:
-
m == board.length n == board[i].length 1 <= m, n <= 12 board[i][j] 是一个小写英文字母 1 <= words.length <= 3 * 104 1 <= words[i].length <= 10 words[i] 由小写英文字母组成 words 中的所有字符串互不相同
思路:前缀树+dfs
如果给我们一个二维字符网格和一个字符串,然我们检查字符串是否在二维网格中出现,我们可以很容易写出,先遍历二维网格,如果有和字符串开头相同的字符则使用dfs查找是否存在。题目中给出的是一个字符串列表,我们需要考虑如何快速在这个列表中出以这个字符开头的字符串,显而易见我们可以使用字典序查找。
具体算法:
-
先构建一颗字典树 然后在使用dfs查找
class Solution { public class TrieTree{ TrieTree[] next; String end; public TrieTree(){ next = new TrieTree[26]; end = null; } } public List<String> findWords(char[][] board, String[] words) { List<String> ans = new ArrayList<>(); if(board.length == 0 || board[0].length == 0) return ans; TrieTree root = new TrieTree(); TrieTree p = root; // 构建前缀树 int n = words.length; for(int i = 0; i < n; i++) { p = root; for(int j = 0; j < words[i].length(); j++) { int ind = words[i].charAt(j) - a; if(p.next[ind] == null) p.next[ind] = new TrieTree(); p = p.next[ind]; } p.end = words[i]; } n = board.length; int m = board[0].length; is = new boolean[n][m]; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(root.next[board[i][j] - a] != null) { check(root, board, i, j, ans, n, m); } } } return ans; } boolean[][] is; private void check(TrieTree root, char[][] board, int i, int j, List<String> ans, int n, int m) { if(i < 0 || j < 0 || i >= n || j >= m || is[i][j] || root.next[board[i][j] - a] == null) return; int ind = board[i][j] - a; if(root.next[ind].end != null) { ans.add(root.next[ind].end); root.next[ind].end = null; } is[i][j] = true; check(root.next[ind], board, i + 1, j, ans, n, m); check(root.next[ind], board, i - 1, j, ans, n, m); check(root.next[ind], board, i, j + 1, ans, n, m); check(root.next[ind], board, i, j - 1, ans, n, m); is[i][j] = false; } }