leetcode 212-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.
For example,
Given words = ["oath","pea","eat","rain"]
and board =
[ ['o','a','a','n'], ['e','t','a','e'], ['i','h','k','r'], ['i','f','l','v'] ]
Return ["eat","oath"]
.
Note:
You may assume that all inputs are consist of lowercase letters a-z
.
题意:从word数组中找出能由字符矩阵board构成的单词。
思路:根据提示,考虑使用Tire Tree。
1. Trie由word单词构成。
2. TrieTree构造好后,深度遍历board,如果当前遍历得到的字符串不是Trie Tree的前缀,则删除这个遍历分支;
3. 由于出现同一个单词多次计算的情况(如board=[a,a], word=[a]),采用set保存结果,并最后由set构造一个list.
实现:
1. 构造Trie Tree。 Trie Tree包含
insertWord(String str) //插入单词
insertNode(char c) //插入节点,被insertWord调用
isPrefix(String str) //判断str是否是Trie Tree的前缀
contains(String str) //判断str是否是出现在Trie Tree的单词
代码如下:
1 class TrieNode{ 2 public boolean isWord; 3 public TrieNode[] childs; 4 public TrieNode() { 5 isWord = false; 6 childs = new TrieNode[26]; 7 } 8 9 public void insertNode(char c) { 10 if(this.childs[c-'a'] == null) 11 this.childs[c-'a'] = new TrieNode(); 12 } 13 14 public void insertWord(String str) { 15 TrieNode root = this; 16 for(int i=0; i<str.length(); i++) { 17 root.insertNode(str.charAt(i)); 18 root = root.childs[str.charAt(i)-'a']; 19 } 20 root.isWord = true; 21 } 22 23 public boolean isPrefix(String str) { 24 TrieNode root = this; 25 for(int i=0; i<str.length(); i++) { 26 if(root.childs[str.charAt(i)-'a'] == null) 27 return false; 28 root = root.childs[str.charAt(i)-'a']; 29 } 30 return true; 31 } 32 33 public boolean contains(String str) { 34 TrieNode root = this; 35 for(int i=0; i<str.length(); i++) { 36 if(root.childs[str.charAt(i)-'a'] == null) 37 return false; 38 root = root.childs[str.charAt(i)-'a']; 39 } 40 return root.isWord; 41 } 42 }
2. 有了Trie Tree后,使用DFS遍历board。题目要求同一个单词的匹配过程中,board中同一个字符只能使用一次,因此需要记录某个字符是否已经被匹配。
这里使用一个标记矩阵来表示boolean visited[board.length][board[0].length];
1 void findWord(char[][] board, TrieNode root, boolean[][] visited, int x, int y, String curr) { 2 if(x<0 || x >=board.length || y<0 || y>=board[0].length || visited[x][y]) return ; 3 4 curr += board[x][y]; 5 if(!root.isPrefix(curr)) return; 6 if(root.contains(curr)) { 7 list.add(curr); 8 } 9 visited[x][y] = true; 10 findWord(board, root, visited, x-1, y, curr); 11 findWord(board, root, visited, x+1, y, curr); 12 findWord(board, root, visited, x, y-1, curr); 13 findWord(board, root, visited, x, y+1, curr); 14 visited[x][y] = false; 15 }
3. 主方法代码如下:
1 public List<String> findWords(char[][] board, String[] words) { 2 TrieNode root = new TrieNode(); 3 for(String str : words) 4 root.insertWord(str); 5 6 7 for(int i=0; i<board.length; i++) { 8 for(int j=0; j<board[0].length; j++) { 9 findWord(board, root, new boolean[board.length][board[0].length], i, j, ""); 10 } 11 } 12 return new ArrayList<String>(list); 13 }
posted on 2015-05-20 21:03 linxiong1991 阅读(194) 评论(0) 编辑 收藏 举报