Word Search II
问题:
Given a 2D board and a list of words from the dictionary, find all words in the board.
Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
思路:
回溯
我的代码:
public class Solution { private Trie trie = new Trie(); private List<String> list = new ArrayList<String>(); public List<String> findWords(char[][] board, String[] words) { if(board==null || board.length==0 || board[0].length ==0 || words==null || words.length==0) return list; for(String word: words) trie.insert(word); int row = board.length; int col = board[0].length; boolean[][] isVisited = new boolean[row][col]; for(int i = 0; i < row; i++) { for(int j = 0; j < col; j++) { if(trie.startsWith(String.valueOf(board[i][j]))) { isVisited[i][j] = true; helper(board, ""+board[i][j], i, j, isVisited, row, col); isVisited[i][j] = false; } } } return list; } public void helper(char[][] board, String word, int i, int j, boolean[][] isVisited, int row, int col) { if(trie.search(word)) { if(!list.contains(word)) list.add(word); } //left if(j > 0 && isVisited[i][j-1] == false && trie.startsWith(word+board[i][j-1])) { isVisited[i][j-1] = true; helper(board, word+board[i][j-1], i, j-1, isVisited, row, col); isVisited[i][j-1] = false; } //right if(j < col - 1 && isVisited[i][j+1] == false && trie.startsWith(word+board[i][j+1])) { isVisited[i][j+1] = true; helper(board, word+board[i][j+1], i, j+1, isVisited, row, col); isVisited[i][j+1] = false; } //up if(i > 0 && isVisited[i-1][j] == false && trie.startsWith(word+board[i-1][j])) { isVisited[i-1][j] = true; helper(board, word+board[i-1][j], i-1, j, isVisited, row, col); isVisited[i-1][j] = false; } //down if(i < row-1 && isVisited[i+1][j] == false && trie.startsWith(word+board[i+1][j])) { isVisited[i+1][j] = true; helper(board, word+board[i+1][j], i+1, j, isVisited, row, col); isVisited[i+1][j] = false; } } class TrieNode { char c; boolean leaf; HashMap<Character, TrieNode> children = new HashMap<Character, TrieNode>(); public TrieNode(char c) { this.c = c; } public TrieNode(){}; } class Trie { private TrieNode root; public Trie() { root = new TrieNode(); } public void insert(String word) { Map<Character, TrieNode> children = root.children; for(int i=0; i<word.length(); i++) { char c = word.charAt(i); TrieNode t; if(children.containsKey(c)) { t = children.get(c); } else { t = new TrieNode(c); children.put(c, t); } children = t.children; if(i==word.length()-1) t.leaf=true; } } public boolean search(String word) { TrieNode t = searchNode(word); return t!=null && t.leaf; } public boolean startsWith(String prefix) { return searchNode(prefix) != null; } private TrieNode searchNode(String word) { Map<Character, TrieNode> children = root.children; TrieNode t = null; for(int i=0; i<word.length(); i++) { char c = word.charAt(i); if(!children.containsKey(c)) return null; t = children.get(c); children = t.children; } return t; } } }
他人代码:
ublic class Solution { Set<String> res = new HashSet<String>(); public List<String> findWords(char[][] board, String[] words) { Trie trie = new Trie(); for (String word : words) { trie.insert(word); } int m = board.length; int n = board[0].length; boolean[][] visited = new boolean[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { dfs(board, visited, "", i, j, trie); } } return new ArrayList<String>(res); } public void dfs(char[][] board, boolean[][] visited, String str, int x, int y, Trie trie) { if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) return; if (visited[x][y]) return; str += board[x][y]; if (!trie.startsWith(str)) return; if (trie.search(str)) { res.add(str); } visited[x][y] = true; dfs(board, visited, str, x - 1, y, trie); dfs(board, visited, str, x + 1, y, trie); dfs(board, visited, str, x, y - 1, trie); dfs(board, visited, str, x, y + 1, trie); visited[x][y] = false; } }
学习之处: