• 单词搜索 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
  • 相关阅读:
    oracle拼接函数:将多个字段拼接在一行显示
    Source Insight 自定义命令说明
    harview .har文件解析
    GSM设备和网络错误代码
    mknod 创建设备
    linux下的usb抓包方法
    一些函数
    vmware 软件打开 自动开启虚拟机(快捷方式)
    Unix下C程序内存泄漏检测工具Valgrind安装与使用
    windows vmware 系统自启动
  • 原文地址:https://www.cnblogs.com/immiao0319/p/8471415.html
Copyright © 2020-2023  润新知