zoukankan      html  css  js  c++  java
  • 212. Word Search II

    一、题目

      1、审题

      

      2、分析

        给出一个二维字符矩阵 board,一个字符串数组 words。求出矩阵中连续的字符能组成的 words 中的单词,一个单词只能用同一个位置的字符一次。

    二、解答

      1、思路:

        采用 Trie 字典树。

        ①、根据 words 创建 一个 Trie

        ②、遍历 board,以每个字符为起始字符,在 Trie 中以 DFS 查找是否存在此 word

     1 class Solution {
     2     public List<String> findWords(char[][] board, String[] words) {
     3         List<String> result = new ArrayList<String>();
     4         // 1、构造查找字典
     5         TrieNode root = buildTrie(words);
     6         
     7         // 2、 从每一个字符开始 dfs 查找是否有存在的单词
     8         for (int i = 0; i < board.length; i++) {
     9             for (int j = 0; j < board[0].length; j++) {
    10                 dfs(board, i, j, root, result);
    11             }
    12         }
    13         
    14         return result;
    15     }
    16 
    17     private void dfs(char[][] board, int i, int j, TrieNode node,
    18             List<String> result) {
    19         char c = board[i][j];
    20         if(c == '#' || node.children[c - 'a'] == null)
    21             return;
    22         node = node.children[c - 'a'];
    23         if(node.word != null) {    // found one
    24             result.add(node.word);
    25             node.word = null;
    26         }
    27         
    28         board[i][j] = '#';
    29         if(i > 0)
    30             dfs(board, i - 1, j, node, result);
    31         if(j > 0)
    32             dfs(board, i, j - 1, node, result);
    33         if(i < board.length - 1)
    34             dfs(board, i + 1, j, node, result);
    35         if(j < board[0].length - 1)
    36             dfs(board, i, j + 1, node, result);
    37         board[i][j] = c;
    38     }
    39 
    40     private TrieNode buildTrie(String[] words) {
    41         TrieNode root = new TrieNode();
    42         for(String word: words) {
    43             TrieNode node = root;
    44             for(char c: word.toCharArray()) {
    45                 int i = c - 'a';
    46                 if(node.children[i] == null)
    47                     node.children[i] = new TrieNode();
    48                 node = node.children[i];
    49             }
    50             node.word = word;
    51         }
    52         return  root;
    53     }
    54 }
    55 
    56 class TrieNode {
    57     public boolean isWord;
    58     public TrieNode[] children = new TrieNode[26];
    59     public String word;
    60 
    61 }

      2、方法二,不使用字典树。采用一个 Boolean 数组记录当前位置是否访问过。

        public List<String> findWords(char[][] board, String[] words) {
            
            int rows = board.length;
            int cols = board[0].length;
            List<String> result = new ArrayList<String>();
            boolean[][] IS_USED = new boolean[rows][cols];
    
            for(String word: words) {
                for (int row = 0; row < rows; row++) {
                    for (int col = 0; col < cols; col++) {
                        char[] cArray = word.toCharArray();
                        if(is_pattered(board, row, col, rows, cols, IS_USED, 0, word.length() - 1, cArray)) 
                            result.add(word);
                    }
                }
            }
            
            return new ArrayList<String>(new HashSet<String>(result));
        }
    
        private boolean is_pattered(char[][] board, int row, int col, int rows, int cols, boolean[][] iS_USED, int start, int end, char[] cArray) {
            
            if(start > end)
                return true;
            
            if(row >= rows || col >= cols || row < 0 || col < 0)
                return false;
            
            if(board[row][col] != cArray[start] || iS_USED[row][col] == true)
                return false;
            
            iS_USED[row][col] = true;
            
            if(is_pattered(board, row + 1, col, rows, cols, iS_USED, start + 1, end, cArray) ||
                    is_pattered(board, row - 1, col, rows, cols, iS_USED, start + 1, end, cArray) ||
                    is_pattered(board, row, col + 1, rows, cols, iS_USED, start + 1, end, cArray) ||
                    is_pattered(board, row, col - 1, rows, cols, iS_USED, start + 1, end, cArray)
            ) {
                iS_USED[row][col] = false;    // 恢复
                return true;
            }
            
            iS_USED[row][col] = false;
            
            return false;
        }
  • 相关阅读:
    合并、媒体查询
    混入、命名空间(less)、继承
    函数(内置函数 和 自定义函数)
    运算、单位、转义、颜色
    选择器嵌套、伪类嵌套、属性嵌套(只在Sass中)
    注释、变量、插值、作用域
    二路归并排序java实现
    堆排序Java实现
    和为S的连续正数序列——牛客网(剑指offer)
    transient 与 volatile 笔记
  • 原文地址:https://www.cnblogs.com/skillking/p/9885933.html
Copyright © 2011-2022 走看看