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


    June-21-2019

    Trie + word search是CS1501的作业题,当时做了1个月。
    DFS + backtrack + trie,正好复习了一下dfs + backtrack
    说说做错的地方:
    一开始是用board[][]建字典,枚举所有可能,然后在里面搜索words,这样建树花时间太长太长了,相当于枚举出board[][]可以组成的所有单词= =。正确的方法是,通过words建树,然后在board里找,很多情况都可以直接剪枝。
    第二个错的地方是,Trie完全没吊用。。记住Root就行,所以一个class足够。然后isLetter其实是说isWord,刚才几个题也写错了,不知道在想什么。
    第三个是,DFS是下去的那层来判断是否找到word,要在边界check之前完成;
    第四个是,不一定非要boolean[][]可以通过+26变大写之类的来代表visited
    另外:
    上下左右用了个小trick
    字母类还是Node[26]好一些
    DFS回溯没做错= =不容易

    class Solution {
                                                 // 1  0  -1  0
        private static final int[] MOVE = new int[]{0, 1, 0, -1, 0};
        
        public class Node {
            Character letter;
            boolean isLetter;
            Node[] nextLevel;
            
            public Node(Character c) {
                this.letter = c;
                this.isLetter = false;
                nextLevel = new Node[26];
            }
        }
        
        public class Trie {
            Node root;
            
            public Trie() {
                root = new Node(null);
            }
            
            public void add(String word) {
                Node temp = root;
                for (char c : word.toCharArray()) {
                    if (temp.nextLevel[c - 'a'] == null) {
                        temp.nextLevel[c - 'a'] = new Node(c);
                    }
                    temp = temp.nextLevel[c - 'a'];
                }
                temp.isLetter = true;
            }
            
            public boolean contains(String word) {
                Node temp = root;
                for (char c : word.toCharArray()) {
                    if (null == temp.nextLevel[c - 'a']) {
                        return false;
                    } else {
                        temp = temp.nextLevel[c - 'a'];
                    }
                }
                return temp.isLetter;
            }
            
        }
        
        
        public List<String> findWords(char[][] board, String[] words) {
            Trie dict = new Trie();
            
            for (String word : words) {
                dict.add(word);
            }
    
            List<String> result = new ArrayList<>();
            boolean[][] visited = new boolean[board.length][board[0].length];
            
            for (int i = 0; i < board.length; i ++) {
                for (int j = 0; j < board[0].length; j ++) {
                    contains(dict.root, i, j, visited, board, new StringBuilder(), result);
                }
            }
            
            return result;
    
        }
        
        public void contains(Node temp, int i, int j, boolean[][] visited, char[][] board, StringBuilder sb, List<String> res) {
            if (temp.isLetter && !res.contains(sb.toString())) {
                res.add(sb.toString());
            }
            if (i < 0 || i >= visited.length || j < 0 || j >= visited[0].length || visited[i][j]) return;
            char tempC = board[i][j];
            if (temp.nextLevel[tempC - 'a'] == null) return;
            temp = temp.nextLevel[tempC - 'a'];
            visited[i][j] = true;
            sb.append(board[i][j]);
            int length = sb.length();
            
            
            for (int m = 0; m < 4; m ++) {
                int horizontal = MOVE[m];
                int vertical = MOVE[m + 1];
                contains(temp, i + horizontal, j + vertical, visited, board, sb, res);
                sb.setLength(length);
            }
            visited[i][j] = false;  
        }
    }
    
  • 相关阅读:
    [Noip2016]天天爱跑步
    [ioi2008]Island 岛屿
    [Poi2012]Rendezvous
    RCTF2019 next_php
    WinSocket编程笔记(五)
    PTA的Python练习题(二十一)
    WinSocket编程笔记(四)
    PTA的Python练习题(二十)
    WinSocket编程笔记(三)
    WinSocket编程笔记(二)
  • 原文地址:https://www.cnblogs.com/reboot329/p/11065333.html
Copyright © 2011-2022 走看看