LeetCode 212. Word Search II(dfs + 字典树)

题目来源:https://leetcode.com/problems/word-search-ii/

问题描述

212. Word Search II

Hard

Given a 2D board and a list of words from the dictionary, find all words in the board.

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

 

Example:

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"]

 

Note:

  1. All inputs are consist of lowercase letters a-z.
  2. The values of words are distinct.

------------------------------------------------------------

题意

给定一个字母矩阵和一个单词表,求所有既在单词表中,又在字母矩阵中的所有单词。“在字母矩阵”的定义是组成单词的各个字母在字母矩阵中按顺序且连续,可以有拐弯。

------------------------------------------------------------

思路

dfs. 用字典树存储单词表,dfs的时候通过前缀是否在字典树中做剪枝。

注意字典树节点类的word属性为以此节点为终点的字符串,为了避免结果含有重复的字符串,如果某个字典树节点的word属性已经添加进结果中了,则把该属性置为null. 还有为了防止搜索过程中重复经过同一个单元格,一次搜索过程中访问过的单元格要变成一个a-z以外的字符。

------------------------------------------------------------

代码

class Solution {
    class TierNode {
        public String word;
        public TierNode[] next;
        
        public TierNode() {
            next = new TierNode[26];
        }
    }
    
    private TierNode root;
    
    private void tierAdd(String word) {
        TierNode tn = root;
        for (char ch: word.toCharArray()) {
            int tmp = ch - 'a';
            if (tn.next[tmp] == null) {
                tn.next[tmp] = new TierNode();
            }
            tn = tn.next[tmp];
        }
        tn.word = word;
    }
    
    private void dfs(char[][] board, int x, int y, TierNode ptr, List ans) {
        int m = board.length, n = board[0].length;
        if (board[x][y] == '.') {
            return;
        }
        int tmp = board[x][y] - 'a';
        if (ptr.next[tmp] == null) {
            return;
        }
        ptr = ptr.next[tmp];
        char saved = board[x][y];
        board[x][y] = '.';          // the same letter cell may not be used more than once in a word
        if (ptr.word != null) {
            ans.add(ptr.word);
            ptr.word = null;        // prevent duplicate in ans list
        }
        if (x + 1 < m) {
            dfs(board, x+1, y, ptr, ans);
        }
        if (x - 1 >= 0) {
            dfs(board, x-1, y, ptr, ans);
        }
        if (y + 1 < n) {
            dfs(board, x, y+1, ptr, ans);
        }
        if (y - 1 >= 0) {
            dfs(board, x, y-1, ptr, ans);
        }
        board[x][y] = saved;
    }
    
    public List findWords(char[][] board, String[] words) {
        List ans = new ArrayList();
        int m = board.length;
        if (m == 0) {
            return ans;
        }
        int n = board[0].length;
        if (n == 0) {
            return ans;
        }
        root = new TierNode();
        for (String word: words) {
            tierAdd(word);
        }
        for (int x=0; x

 

你可能感兴趣的:(LeetCode,LeetCode,Hard,Java,dfs,字典树)