zoukankan      html  css  js  c++  java
  • 单词搜索 II · Word Search II

    [抄题]:

    给出一个由小写字母组成的矩阵和一个字典。找出所有同时在字典和矩阵中出现的单词。一个单词可以从矩阵中的任意位置开始,可以向左/右/上/下四个相邻方向移动。

    给出矩阵:

    doaf
    agai
    dcan

    和字典:

    {"dog", "dad", "dgdg", "can", "again"}
     
    返回 {"dog", "dad", "can", "again"}

     [暴力解法]:

    时间分析:

    空间分析:

    [思维问题]:

    1. 用p指针进行比较,不知道指针应该怎么用,指针就是一个新类,利用其中的TrieNode[] next数组移动即可。表示节点的初始化,
    2. p = p.next[c - 'a'];使节点等于初始化之后的值。
    3. 为防止出现res中有相同单词,每添加一个单词后就设其为空, 不同路线相同结果时要想到

    [一句话思路]:

    [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

    [画图]:

    在trie的结构中,字母其实是线段和下一个节点共有的,所以trienode中的节点数组命名为next

    建树时,每个单词都用p从root开始重新新建

    [一刷]:

    1. dfs的参数在总函数中有用的变量一一对应就行了,数组名还是要有的
    2. next[],忘记了 数组括号中一定只能是数字,不能是别的,应该是c - 'a'
    3. board[i][j]直接= 字母c就行了,不用加‘’
    4. 纠结不清的:dfs的表达式上限是由总表达式的上限决定的,
      i < board.length, dfs(i+1)也要带入后符合规则,故
      i < board.length - 1

    [二刷]:

    1. 当前字母对应的节点p.next[c - 'a'];非空时,说明trie中已经存了和图中相对应的节点,p就应该指向当前对应的字母节点,否则新建。没有理解
    2. w循环时,其对应的每个单词都要加入到p.word中,没有条件,不理解

    [三刷]:

    [四刷]:

    [五刷]:

      [五分钟肉眼debug的结果]:

    [总结]:

    1. 当前字母对应的节点p.next[c - 'a'];非空时,说明trie中已经存了和图中相对应的节点,p就应该指向当前对应的字母节点,否则新建。没有理解

    [复杂度]:Time complexity: O(4*深度次方,最大m+n) Space complexity: O(<n)

    [英文数据结构或算法,为什么不用别的数据结构或算法]:

    1. 新建的一棵trie树,按道理应该习惯命名为root
    2. 可以有几个类,但是只能有一个public的类 其他的你就只能定义class而已
    3. 当 java 一个 class 里面 包含 另一个 class 时,需要将这个子 class 声明为 static,不然经常出错

    [关键模板化代码]:

    for (String w : words){
                TrieNode p = root;
            //add a c            
                for (char c : w.toCharArray()) {
                    int i = c - 'a';
                    if (p.next[i] == null) {
                        p.next[i] = new TrieNode();
                    }
                    //asign!
                    p = p.next[i];
                }
            //add word
            p.word = w;//only mean to w, sure to have word
            }
    指针开始指向root,之后指向别的

    [其他解法]:

    [Follow Up]:

    [LC给出的题目变变变]:

    word search1 : dfs

     [代码风格] :

    j的for循环写成i了,查了半小时,后悔死。好像老是出现这个错误吧?要避免。

    class Solution {
        //class
        class TrieNode {
            TrieNode[] next = new TrieNode[26];
            String word;
        }
        
        public List<String> findWords(char[][] board, String[] words) {
            List<String> res = new ArrayList<String>();
            TrieNode root = buildTrie(words);
            
            for (int i = 0; i < board.length; i++) {
                for (int j = 0; i < board[0].length; j++) {
                    dfs(board, i, j, root, res);
                }
            }
            return res;
        }
        //dfs
        public void dfs(char[][] board, int i, int j, TrieNode p, List<String> res) {
            //exit
            //no c or no node
            char c = board[i][j];
            if (c == '#' || p.next[c - 'a'] == null) {//exit in dfs
                return ;
            }
            //asign
            p = p.next[c - 'a'];
            //add word
            if (p.word != null) {
                res.add(p.word);
                p.word = null;
            }
            //dfs
            board[i][j] = '#';
            if (i < board.length - 1) dfs(board, i + 1, j, p, res);
            if (j < board[0].length - 1) dfs(board, i, j + 1, p, res);
            if (i > 0) dfs(board, i - 1, j, p, res);
            if (j > 0) dfs(board, i, j - 1, p, res);
            board[i][j] = c;
        }
            //buildTrie
        public TrieNode buildTrie (String[] words) {
            //build a root
            TrieNode root = new TrieNode();
            //add all words's node
            for (String w : words){
                TrieNode p = root;
            //add a c            
                for (char c : w.toCharArray()) {
                    int i = c - 'a';
                    if (p.next[i] == null) {
                        p.next[i] = new TrieNode();
                    }
                }
            //add word
            if (p.word != null) {
                res.add(p.word);
            }
            }
        return root;
        }
    }
    View Code
  • 相关阅读:
    WPF 关于拖拽打开文件的注意事项
    asp.net core 3.1中对Mongodb BsonDocument的序列化和反序列化支持
    用百度webuploader分片上传大文件
    多线程学习笔记
    web.config数据库连接字符串加密
    Visual Studio 2010 常用快捷方式
    Team Foundation Server 2013 日常使用使用手册(四)分支与合并
    Team Foundation Server 2013 日常使用使用手册(三)上传新工程、创建任务、创建bug、设置预警
    Team Foundation Server 2013 日常使用使用手册(二)修改、签入、撤销、回滚、对比代码变更
    Team Foundation Server 2013 日常使用使用手册(一)-本地连接TFS、查看任务
  • 原文地址:https://www.cnblogs.com/immiao0319/p/8471415.html
Copyright © 2011-2022 走看看