#212 Word Search II

Description

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.

Examples

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.

思路

首先这个数据量是肯定需要剪枝的,剪枝策略可以通过前缀树实现,适用于share相同前缀的各个情况,不用每次都从头开始计算。
所以步骤就是先对要检测的String数组构建前缀树,再用dfs对这棵树进行搜索,得到最后的答案序列。

思路没有什么需要深究的地方,有了想法之后,直接写就行了,也没有特别的细节,但我这份的运行速度特别慢,应该里面还有一些可以优化的地方,下次做的时候再考虑一下。

代码

class TrieNode {
    char ch;
    String str;
    TrieNode[] next;
    
    public TrieNode(char c){
        this.ch = c;
        next = new TrieNode[26];
        str = null;
    }
}

class Solution {
    List<String> answer = new ArrayList<>();
    
    public TrieNode buildTrie(String[] words) {
        TrieNode root = new TrieNode('$');
        
        for (String word: words) {
            char[] chars = word.toCharArray();
            TrieNode tmp = root;
            for (char ch: chars) {
                if (tmp.next[ch - 'a'] == null) {
                    TrieNode newNode = new TrieNode(ch);
                    tmp.next[ch - 'a'] = newNode;
                }
                tmp = tmp.next[ch - 'a'];
            }
            tmp.str = word;
        }
        
        return root;
    }
    
    public void dfs_visit(char[][] board, TrieNode node, int x, int y) {
        if (x < 0 || x >= board.length || y < 0 || y >= board[x].length)
            return;
        if (node == null || board[x][y] != node.ch)
            return;
        
        if (node.str != null) {
            answer.add(node.str);
            node.str = null;
        }
        
        board[x][y] = '#';
        for (TrieNode next: node.next) {
            dfs_visit(board, next, x + 1, y);
            dfs_visit(board, next, x - 1, y);
            dfs_visit(board, next, x, y + 1);
            dfs_visit(board, next, x, y - 1);
        }
        board[x][y] = node.ch;
    }
    
    public List<String> findWords(char[][] board, String[] words) {
        TrieNode root = buildTrie(words);
        
        for (TrieNode starter: root.next) {
            if (starter == null)
                continue;
            for (int i = 0; i < board.length; i++) {
                for (int j = 0; j < board[i].length; j++) {
                    if (board[i][j] == starter.ch)
                        dfs_visit(board, starter, i, j);
                }
            }
        }
        
        return answer;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值