Leetcode 212 Woed Search II 笔记

192 阅读2分钟

Hard

思路

  • 因为多个目标单词,会有许多common prefix,所以采用字典树(trie tree),之后DFS(类似Word Search I)
  • 建立trie tree
class TrieNode{
//定义变量
	char val;
    TrieNode[] children;
    String word;
//初始化    
    public TrieNode(char x){
    	children = new TrieNode[26];
        word = null;
    }
}
public void build(TrieNode root, String[] words){
        for(String s : words){
            TrieNode cur = root; //cureent 指针节点帮助扫整个树
            for(char c : s.toCharArray())// 当前要加入trie tree的字符是c
            {
                if(cur.children[c - 'a'] == null //判断c所在的位置是否为null,用来判断该树中是否有c开头的单词
                {
                    cur.children[c - 'a'] = new TrieNode(c);//cur 节点的children(c-‘a')位置new了一个新节点,值为c
                }
                cur = cur.children[c - 'a']; //cur 指针下移
            }
            cur.word = s;//标记一个单词记录完毕
        }
}

过程

  • new 一个 trie tree 的根结点 TrieNode root = new TrieNode('');
  • 先把所有目标单词存入trie tree, 之后在遍历二维数组的同时对不null的节点进行深搜
  • DFS大致与之前的word search I 一致,不同在于以current node为指针遍历
  • 返回值是个list,所以dfs是void函数,每次在list里add word就可以
  • base case: 出界返回, c == * 返回, c-‘a'为null返回
  • cur 移到[c-'a']
  • 当判定成功,加到res中,之后要把当前cur带string的节点变为null,为之后更长的单词不出错
  • 之后把board[i][j]变为* 后开始dfs
  • dfs结束后要把board[i][j]变回来

代码

class TrieNode {
    char val;
    TrieNode[] children;
    String word;
    
    public TrieNode(char x){
        children = new TrieNode[26];
        word = null;
    }
}
class Solution {
    public void buildTrie (TrieNode root, String[] words){
       for(String s : words){
           TrieNode cur = root;
           for(char c : s.toCharArray()){
               if(cur.children[c - 'a'] == null) cur.children[c - 'a'] = new TrieNode(c);
               cur = cur.children[c - 'a'];
           }
           cur.word = s;
       }
   }
    
    public List<String> findWords(char[][] board, String[] words) {
        List<String> res = new ArrayList<>();
        if(board == null || board.length == 0 || board[0].length == 0 || words.length == 0)
            return res;
        
        TrieNode root = new TrieNode(' ');
        buildTrie(root, words);
        for(int i = 0; i < board.length ;i++){
            for(int j = 0; j < board[0].length; j++){
                char c = board[i][j];
                if(root.children[c - 'a'] != null)
                    dfs(board, res, i, j, root);
            }
        }
        return res;
    }
    
    public void dfs(char[][] board, List<String> res, int i, int j, TrieNode cur){
        if(i < 0 || i >= board.length||j < 0 || j >= board[0].length) return;
        char c = board[i][j];
        if(c == '*' || cur.children[c - 'a'] == null) return;
        cur = cur.children[c - 'a'];
        if(cur.word != null){
            res.add(cur.word);
            cur.word = null;
        }
       
        board[i][j] = '*';
        
        dfs(board, res, i + 1, j + 0, cur);
        dfs(board, res, i - 1, j + 0, cur);
        dfs(board, res, i + 0, j + 1, cur);
        dfs(board, res, i + 0, j - 1, cur);
       
        board[i][j] = c;
    }
    
}