212. 单词搜索 II

题目:

思路:

【1】常规的模拟方法(这种直接就超时了)

【2】回溯 + 字典树

【3】删除被匹配的单词

代码展示:

【1】常规的模拟方法(这种直接就超时了)

class Solution {
    public List<String> findWords(char[][] board, String[] words) {
        boolean[] flag = new boolean[words.length];
        int row = board.length, col = board[0].length;
        boolean[][] boardFlag;
        for (int i = 0; i < row; i++){
            for (int j = 0; j < col; j++){
                for (int k = 0; k < words.length; k++){
                    if (!flag[k]){
                        boardFlag = new boolean[row][col];
                        flag[k] = checkString(board,i,j,boardFlag,words[k],0);
                    }
                }
            }
        }
        ArrayList<String> res = new ArrayList<>();
        for (int k = 0; k < words.length; k++){
            if (flag[k]) res.add(words[k]);
        }
        return res;
    }

    private boolean checkString(char[][] board,int row,int col,boolean[][] boardFlag,String word,int k){
    
        if (board[row][col] != word.charAt(k) || boardFlag[row][col]) return false;
        if (k >= word.length()-1) return true;
        boardFlag[row][col] = true;
        // 上下左右
        int[][] dire = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
        int rowBord = board.length, colBord = board[0].length;
        boolean res = false;
        for (int[] d : dire){
            int newRow = row+d[0];
            int newCol = col+d[1];
            // 必须要在边界值内才行,不然会数组溢出
            if (newRow >= 0 && newCol>=0 && newRow < rowBord && newCol< colBord){
                boardFlag[row][col] = true;
                res = res || checkString(board,newRow,newCol,boardFlag,word,k+1);
                // 这里要对标记的走过位置进行复原
                boardFlag[row][col] = false;
            }
            if (res) return true;
        }
        return res;
    }
}

 

【2】回溯 + 字典树

//时间548 ms 击败 46.4%
//内存42.8 MB 击败 56.76%
class Solution {
    int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    public List<String> findWords(char[][] board, String[] words) {
        Trie trie = new Trie();
        for (String word : words) {
            trie.insert(word);
        }

        Set<String> ans = new HashSet<String>();
        for (int i = 0; i < board.length; ++i) {
            for (int j = 0; j < board[0].length; ++j) {
                dfs(board, trie, i, j, ans);
            }
        }

        return new ArrayList<String>(ans);
    }

    public void dfs(char[][] board, Trie now, int i1, int j1, Set<String> ans) {
        if (!now.children.containsKey(board[i1][j1])) {
            return;
        }
        char ch = board[i1][j1];
        now = now.children.get(ch);
        if (!"".equals(now.word)) {
            ans.add(now.word);
        }

        board[i1][j1] = '#';
        for (int[] dir : dirs) {
            int i2 = i1 + dir[0], j2 = j1 + dir[1];
            if (i2 >= 0 && i2 < board.length && j2 >= 0 && j2 < board[0].length) {
                dfs(board, now, i2, j2, ans);
            }
        }
        board[i1][j1] = ch;
    }
}

class Trie {
    String word;
    Map<Character, Trie> children;
    boolean isWord;

    public Trie() {
        this.word = "";
        this.children = new HashMap<Character, Trie>();
    }

    public void insert(String word) {
        Trie cur = this;
        for (int i = 0; i < word.length(); ++i) {
            char c = word.charAt(i);
            if (!cur.children.containsKey(c)) {
                cur.children.put(c, new Trie());
            }
            cur = cur.children.get(c);
        }
        cur.word = word;
    }
}

 

 

 

【3】删除被匹配的单词

//时间94 ms 击败 87.93%
//内存42.9 MB 击败 53.38%
class Solution {
    int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    public List<String> findWords(char[][] board, String[] words) {
        Trie trie = new Trie();
        for (String word : words) {
            trie.insert(word);
        }

        Set<String> ans = new HashSet<String>();
        for (int i = 0; i < board.length; ++i) {
            for (int j = 0; j < board[0].length; ++j) {
                dfs(board, trie, i, j, ans);
            }
        }

        return new ArrayList<String>(ans);
    }

    public void dfs(char[][] board, Trie now, int i1, int j1, Set<String> ans) {
        if (!now.children.containsKey(board[i1][j1])) {
            return;
        }
        char ch = board[i1][j1];
        Trie nxt = now.children.get(ch);
        if (!"".equals(nxt.word)) {
            ans.add(nxt.word);
            nxt.word = "";
        }

        if (!nxt.children.isEmpty()) {
            board[i1][j1] = '#';
            for (int[] dir : dirs) {
                int i2 = i1 + dir[0], j2 = j1 + dir[1];
                if (i2 >= 0 && i2 < board.length && j2 >= 0 && j2 < board[0].length) {
                    dfs(board, nxt, i2, j2, ans);
                }
            }
            board[i1][j1] = ch;
        }

        if (nxt.children.isEmpty()) {
            now.children.remove(ch);
        }
    }
}

class Trie {
    String word;
    Map<Character, Trie> children;
    boolean isWord;

    public Trie() {
        this.word = "";
        this.children = new HashMap<Character, Trie>();
    }

    public void insert(String word) {
        Trie cur = this;
        for (int i = 0; i < word.length(); ++i) {
            char c = word.charAt(i);
            if (!cur.children.containsKey(c)) {
                cur.children.put(c, new Trie());
            }
            cur = cur.children.get(c);
        }
        cur.word = word;
    }
}

 

posted @ 2023-07-07 12:15  忧愁的chafry  阅读(7)  评论(0编辑  收藏  举报