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

    原题链接在这里:https://leetcode.com/problems/word-search-ii/

    题目:

    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.

    For example,
    Given words = ["oath","pea","eat","rain"] and board =

    [
      ['o','a','a','n'],
      ['e','t','a','e'],
      ['i','h','k','r'],
      ['i','f','l','v']
    ]
    

    Return ["eat","oath"].

    Note:
    You may assume that all inputs are consist of lowercase letters a-z.

    题解:

    Word Search的进阶版题目,同时可以利用Implement Trie (Prefix Tree).

    生成Trie树,把所有的词都insert进去。

    然后从board上的每一个char开始dfs查找。

    终止条件有两个, 一个 i 和 j 出界,或者board[i][j]已经用过了. 另一个是把board[i][j]加到当前item后,若没有以更新过item为prefix的时候就可以返回了.

    search 更新过的item, 若是有就加到res中, 并且继续,这里不能return, 因为有可能有 "aabc" "aabcb"两个词同时存在的情况,只检查了"aabc"就return会漏掉"aabcb".

    标记当前used为true, 然后board四个方向都做recursion. used再改回来.

    Note: 如果board 是[a a], words 只有一个[a], 此时小心重复加了,所以要用HashSet生成res, 最后再用res生成的List返回。

    m = board.length, n = board[0].length, k = words.length, l 是 word的平均长度.

    Time Complexity: O(k*l + m*n*l*4^l). k*l是简历Trie用时间. m*n是外部循环, l是search Trie时间, 4^l是recursion + backtracking的时间.

    Space: O(k*l + l). k*l是Trie数的大小. 用了l层stack.

    AC Java:

     1 public class Solution {
     2     public List<String> findWords(char[][] board, String[] words) {
     3         HashSet<String> res = new HashSet<String>();
     4         if(words == null || words.length == 0 || board == null || board.length == 0 || board[0].length == 0){
     5             return new ArrayList(res);
     6         }
     7         Trie trie = new Trie();
     8         for(int i = 0; i<words.length; i++){
     9             trie.insert(words[i]);
    10         }
    11         
    12         boolean [][] used = new boolean[board.length][board[0].length];
    13         for(int i = 0; i<board.length; i++){
    14             for(int j = 0; j<board[0].length; j++){
    15                 findHelper(board,trie,used,"",i,j,res);
    16             }
    17         }
    18         return new ArrayList(res);
    19     }
    20     private void findHelper(char[][] board, Trie trie, boolean [][] used, String item, int i, int j, HashSet<String> res){
    21         
    22         if(i<0 || j<0 || i>= board.length || j>=board[0].length || used[i][j]){
    23             return;
    24         }
    25         
    26         item = item+board[i][j];
    27         if(!trie.startsWith(item)){
    28             return;
    29         }
    30         if(trie.search(item)){
    31             res.add(item);
    32         }
    33         used[i][j] = true;
    34         findHelper(board,trie,used,item,i+1,j,res);
    35         findHelper(board,trie,used,item,i-1,j,res);
    36         findHelper(board,trie,used,item,i,j+1,res);
    37         findHelper(board,trie,used,item,i,j-1,res);
    38         used[i][j] = false;
    39     }
    40 }
    41 
    42 
    43 class TrieNode{
    44     String val = "";
    45     TrieNode [] nexts;
    46     public TrieNode(){
    47         nexts = new TrieNode[26];
    48     }
    49 }
    50 class Trie{
    51     private TrieNode root;
    52     public Trie(){
    53         root = new TrieNode();
    54     }
    55     
    56     public void insert(String word){
    57         TrieNode p = root;
    58         for(char c : word.toCharArray()){
    59             if(p.nexts[c-'a'] == null){
    60                 p.nexts[c-'a'] = new TrieNode();
    61             }
    62             p = p.nexts[c-'a'];
    63         }
    64         p.val = word;
    65     }
    66     
    67     public boolean search(String word){
    68         TrieNode p = root;
    69         for(char c : word.toCharArray()){
    70             if(p.nexts[c-'a'] == null){
    71                 return false;
    72             }
    73             p = p.nexts[c-'a'];
    74         }
    75         return p.val.equals(word);
    76     }
    77     
    78     public boolean startsWith(String prefix){
    79         TrieNode p = root;
    80         for(char c : prefix.toCharArray()){
    81             if(p.nexts[c-'a'] == null){
    82                 return false;
    83             }
    84             p = p.nexts[c-'a'];
    85         }
    86         return true;
    87     }
    88 }
  • 相关阅读:
    Python_字典
    Python_字符串方法
    跳转到新页面,加载过程中加入等待过渡的动态效果
    web项目引入第三方jar包,编译时找不到的问题与及解决方案
    Eclipse的debug按钮介绍
    什么是TCP粘包?怎么解决TCP粘包问题?UDP协议存在粘包问题吗?
    使用Java编写TCP协议发送和接收数据接口
    UUID生成唯一的16位随机数
    如何在父页面中操作/获取iframe页面中的元素?这个小问题折腾了我快半个小时,所以记下来吧!
    如何接收APP的请求,并且如何以json字符串的格式封装响应的数据,然后发送回APP
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4944555.html
Copyright © 2011-2022 走看看