算法: TireNode解决搜索词212. Word Search II

Posted 架构师易筋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法: TireNode解决搜索词212. Word Search II相关的知识,希望对你有一定的参考价值。

212. Word Search II

Given an m x n board of characters and a list of strings words, return all words on the board.

Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

Example 1:

Input: board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
Output: ["eat","oath"]

Example 2:

Input: board = [["a","b"],["c","d"]], words = ["abcb"]
Output: []
 

Constraints:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 12
  • board[i][j] is a lowercase English letter.
  • 1 <= words.length <= 3 * 104
  • 1 <= words[i].length <= 10
  • words[i] consists of lowercase English letters.
  • All the strings of words are unique.

TireNode解法

回溯+尝试
直观地说,从每个单元格开始,并尝试在字典中构建一个单词。Backtracking (dfs)是用尽所有可能的方法的强大方法。显然,修剪当当前字符不在任何单词中时,我们需要这样做。

  1. 我们如何立即知道当前字符无效?HashMap?
  2. 我们如何立即知道下一个有效字符是什么?LinkedList?
  3. 但是可以从字符列表中选择下一个字符。“Mutil-LinkedList”?

梳理它们,Trie是自然的选择。请注意:

  1. TrieNode这就是我们所需要的。search并且startsWith没用。
  2. 无需在 TrieNode 存储字符。c.next[i] != null足够。
  3. 永远不要使用c1 + c2 + c3. 使用StringBuilder.
  4. 无需使用O(n^2)额外空间visited[m][n].
  5. 无需使用StringBuilder. 将word自身存储在叶节点就足够了。
  6. 无需使用HashSet重复数据删除。使用“一次性搜索”尝试。
class Solution {
    public List<String> findWords(char[][] board, String[] words) {
        List<String> list = new ArrayList<>();
        TireNode node = buildTireNode(words);
        for (int r = 0; r < board.length; r++) {
            for (int c = 0; c < board[0].length; c++) {
                dfs(board, words, list, node, r, c);
            }
        }
        
        return list;
    }
    
    private void dfs(char[][] board, String[] words, List<String> list, TireNode node, int r, int c) {
        if (r < 0 || c < 0 || r >= board.length || c >= board[0].length) return;
        char ch = board[r][c];
        if (ch == '#' || node.next[ch - 'a'] == null) return;
        node = node.next[ch - 'a'];
        if (node.word != null) { // find one
            list.add(node.word);
            node.word = null; // de-duplicate
        }
        board[r][c] = '#';
        dfs(board, words, list, node, r - 1, c);
        dfs(board, words, list, node, r + 1, c);
        dfs(board, words, list, node, r, c - 1);
        dfs(board, words, list, node, r, c + 1);
        board[r][c] =  ch;
    }
    
    private TireNode buildTireNode(String[] words) {
        TireNode root = new TireNode();
        for (String w: words) {
            TireNode node = root;
            for (char c: w.toCharArray()) {
                int i = c - 'a';
                if (node.next[i] == null) node.next[i] = new TireNode();
                node = node.next[i];
            }
            node.word = w;
        }
        
        return root;
    }
    
    class TireNode {
        TireNode[] next = new TireNode[26];
        String word;
    }
}

参考

https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)

以上是关于算法: TireNode解决搜索词212. Word Search II的主要内容,如果未能解决你的问题,请参考以下文章

212. Word Search II

LeetCode 162. 寻找峰值(二分)/ 212. 单词搜索 II(Trie字典树) / 36. 有效的数独

KMP算法

“在字符矩阵中搜索词/字符串”算法的复杂性

查找多个字符串匹配的算法

ruby 爬虫爬取拉钩网职位信息,产生词云报告