LeetCode 79.单词搜索

161 阅读2分钟

「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」。

题目:给定一个二维字符数组board,和一个字符串word,要求确定是否存在连续的wordboard中,如果存在则返回true,否则false。注意:同一个单元格中的字母不允许被重复使用。

解题思路

同一个单元格内容不能重复使用,回想之前全排列也要求不能重复,当时使用了一个数组来标记已使用的元素,此时也可以考虑设置一个标记数组来标记二位字符数组中元素,每次查询时候都检查是否被使用过即可。

要确定单词是否存在在二维字符数组中,可以从上到下遍历二维字符数组,首先找到单词的第一个元素在二维数组中的位置,将该字符标记为已使用,之后检查该字符上下左右的元素是否和单词的之后元素匹配,依次递归即可确定,递归之后需要将该字符重新标记为未使用。代码如下:

public boolean exist(char[][] board, String word) {
        int row = board.length;
        int column=board[0].length;
        int[][] visited = new int[row][column];
        for(int i=0;i<row;i++){
            for(int j=0;j<column;j++){
                if(board[i][j]==word.charAt(0)){
                    if(dfs(board, i, j, word, visited, 0)){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public boolean dfs(char[][] board, int i, int j, String word, int[][] visited, int k){
        if(k == word.length()){
            return true;
        }
        if(i<0||j<0||i>=board.length||j>=board[0].length){
            return false;
        }
        if(word.charAt(k)!=board[i][j]||visited[i][j]==1){
            return false;
        }
        visited[i][j] = 1;
        boolean res = dfs(board, i-1, j, word, visited, k+1)||dfs(board, i+1, j, word, visited, k+1)
                || dfs(board, i, j-1, word, visited, k+1) || dfs(board, i, j+1, word, visited, k+1);
        visited[i][j] = 0;
        return res;
    }

上述代码耗时90ms,并且使用了一个额外的标记数组来标记字符数组的元素,实际上本题可以通过另一种方式来解决不重复使用的问题,只需要将已经访问的字符修改为字符数组不可能存在的字符,之后递归完成修改为原来字符即可,代码修改如下:

public boolean dfs2(char[][] board, int i, int j, String word, int k){
        if(k == word.length()){
            return true;
        }
        if(i<0||j<0||i>=board.length||j>=board[0].length){
            return false;
        }
        if(word.charAt(k)!=board[i][j]){
            return false;
        }
        char c = board[i][j];
        board[i][j] = '#';
        boolean res = dfs2(board, i-1, j, word, k+1)||dfs2(board, i+1, j, word, k+1)
                || dfs2(board, i, j-1, word, k+1) || dfs2(board, i, j+1, word, k+1);
        board[i][j] = c;
        return res;
    }

此处选择的是将字符修改为#。最终运行耗时84ms。