# 212 Word Search II

找字遊戲。

給一個board,還有一個字典,找board裡面有哪些字典的字,

同一個字不可以用重複的element

[
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
]

一開始想用dfs解,看字典裡的每個字可不可以在board裡面找到,

很不幸的time limit exceeded。

看了別人的解法,#208的Trie加dfs就可以過了。

Concept:

先把字典裡的字存成字典樹,再跑過board裡的每個element,

算出每個element可能形成的string,

再一一檢查這些string是否存在字典樹中,

若是,就存到result。

Pseudocode:

Main:
    create a Trie for words
    create a Set res to save answers
    for each element in board,
        run dfs to find all possible string and check if they are in trie
    return new ArrayList(res)

dfs:
    input: index of current element, string, trie, visited
    check if index is in boundary
    append current element to string
    if trie.startswith(string) can't be found, return
    if trie.search(string) exists
        put string in res
    visited[index] = true
    run dfs for 4 neighbors
    visited[index] = false

Code:

public class Solution {
    Set<String> res = new HashSet<>();
    public List<String> findWords(char[][] board, String[] words) {

        int m = board.length;
        int n = board[0].length;
        boolean[][] visited = new boolean[m][n];
        Trie trie = new Trie();
        for(String w : words){
            trie.insert(w);
        }
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                dfs(board, i, j,"", trie, visited);
            }
        }
        return new ArrayList<String>(res);
    }

    void dfs(char[][] board, int x, int y, String str, Trie trie, boolean[][] visited){
        int m = board.length;
        int n = board[0].length;
        if(x<0 || x>=m || y<0 || y>=n)  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,x-1,y,str,trie,visited);
        dfs(board,x+1,y,str,trie,visited);
        dfs(board,x,y-1,str,trie,visited);
        dfs(board,x,y+1,str,trie,visited);
        visited[x][y] = false;
    }
}
class TrieNode {
    public char val;
    public boolean isWord; 
    public TrieNode[] children = new TrieNode[26];
    public TrieNode() {}
    TrieNode(char c){
        TrieNode node = new TrieNode();
        node.val = c;
    }
}

class Trie {
    private TrieNode root;
    public Trie() {
        root = new TrieNode();
        root.val = ' ';
    }

    public void insert(String word) {
        TrieNode ws = root;
        for(int i = 0; i < word.length(); i++){
            char c = word.charAt(i);
            if(ws.children[c - 'a'] == null){
                ws.children[c - 'a'] = new TrieNode(c);
            }
            ws = ws.children[c - 'a'];
        }
        ws.isWord = true;
    }

    public boolean search(String word) {
        TrieNode ws = root; 
        for(int i = 0; i < word.length(); i++){
            char c = word.charAt(i);
            if(ws.children[c - 'a'] == null) return false;
            ws = ws.children[c - 'a'];
        }
        return ws.isWord;
    }

    public boolean startsWith(String prefix) {
        TrieNode ws = root; 
        for(int i = 0; i < prefix.length(); i++){
            char c = prefix.charAt(i);
            if(ws.children[c - 'a'] == null) return false;
            ws = ws.children[c - 'a'];
        }
        return true;
    }
}

results matching ""

    No results matching ""