剑指 Offer 12. 矩阵中的路径(79. 单词搜索)

题目:

 

 

 

 

 

 

 

 

思路:

【1】思路:采用深度搜索,但首先还是要遍历一遍数组,将哪些下标与第一个字母对应的进行递归查找。【其次,重点在于边界值,数组的上下左右边界,字符的长度边界,还有深度遍历的话应该有一个类似动态规划的数据用于记录标志位,可以采用布尔值,但是布尔值是8bit的,改用int,4bit,更节约空间,0和1替代false和true】,最后考虑剪枝问题,如果不匹配的话,就不应该继续往该路径溢散,如果已经找到则应该提前返回。

代码展示:

另一版更优雅的精细写法:

//时间68 ms击败74.64%
//内存39.3 MB击败80.82%
class Solution {
    public boolean exist(char[][] board, String word) {
        if (board == null || board.length == 0 || board[0].length == 0) return false;
        char[] w = word.toCharArray();
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (doExist(board, w, i, j, 0)) return true;
            }
        }
        return false;
    }
    
    private boolean doExist(char[][] board, char[] w, int i, int j, int idx) {
        if (idx == w.length) return true;
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != w[idx]) return false;
        board[i][j] ^= 256;
        boolean res = doExist(board, w, i+1, j, idx+1) || doExist(board, w, i-1, j, idx+1) || doExist(board, w, i, j+1, idx+1) || doExist(board, w, i, j-1, idx+1);
        board[i][j] ^= 256;
        return res;
    }
}

 

精细版本(虽然看着代码简短了很多,但是相对而言效率上貌似就降低了):

//时间178 ms击败7.91%
//内存41.9 MB击败8.72%
class Solution {
    public boolean exist(char[][] board, String word) {
        int h = board.length, w = board[0].length;
        int index = 0;
        int[][] flag = new int[h][w];
        for (int i = 0; i < h; i++){
            for (int j = 0; j < w; j++){
                if (word.charAt(index) == board[i][j]) {
                    flag[i][j] = 1;
                    if (pathExist(board,i,h,j,w,word,index+1,word.length(),flag)) return true;
                    flag[i][j] = 0;
                }
            }
        }
        return false;
    }

    public boolean pathExist(char[][] board, int h, int max_h, int w, int max_w ,String word , int index, int max_index, int[][] flag) {
        if (index >= max_index) return true;
        int height , wight;
        int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        for (int[] dir : directions){
            height = h + dir[0]; wight = w + dir[1];
            //保持边界不超出
            if (wight >= 0 && wight < max_w && height >= 0 && height < max_h){
                if (flag[height][wight] == 0 && board[height][wight] == word.charAt(index)){
                    flag[height][wight] = 1;
                    if(pathExist(board,height,max_h,wight,max_w,word,index+1,max_index,flag)) return true;
                    flag[height][wight] = 0;
                }
            }
        }
        return false;
    }
}

 

粗略版本:

//时间60 ms击败97.55%
//内存39.5 MB击败65.43%
class Solution {
    public boolean exist(char[][] board, String word) {
        int h = board.length, w = board[0].length;
        int index = 0;
        int[][] flag = new int[h][w];
        for (int i = 0; i < h; i++){
            for (int j = 0; j < w; j++){
                //遍历全部找出匹配的第一个字符
                if (word.charAt(index) == board[i][j]) {
                    //标记下标为使用
                    flag[i][j] = 1;
                    if (pathExist(board,i,h,j,w,word,index+1,word.length(),flag)) return true;
                    //当寻找完后要将下标复位
                    flag[i][j] = 0;
                }
            }
        }
        return false;
    }

    public boolean pathExist(char[][] board, int h, int max_h, int w, int max_w ,String word , int index, int max_index, int[][] flag) {
        if (index >= max_index) return true;
        int height , wight;
        //向左
        height = h; wight = w-1;
        if (wight >= 0 && flag[height][wight] == 0 && board[height][wight] == word.charAt(index)){
            flag[height][wight] = 1;
            if(pathExist(board,height,max_h,wight,max_w,word,index+1,max_index,flag)) return true;
            flag[height][wight] = 0;
        }
        //向右
        height = h; wight = w+1;
        if (wight < max_w && flag[height][wight] == 0 && board[height][wight] == word.charAt(index)){
            flag[height][wight] = 1;
            if(pathExist(board,height,max_h,wight,max_w,word,index+1,max_index,flag)) return true;
            flag[height][wight] = 0;
        }
        //向上
        height = h-1; wight = w;
        if (height >= 0 && flag[height][wight] == 0 && board[height][wight] == word.charAt(index)){
            flag[height][wight] = 1;
            if(pathExist(board,height,max_h,wight,max_w,word,index+1,max_index,flag)) return true;
            flag[height][wight] = 0;
        }
        //向下
        height = h+1; wight = w;
        if (height < max_h && flag[height][wight] == 0 && board[height][wight] == word.charAt(index)){
            flag[height][wight] = 1;
            if(pathExist(board,height,max_h,wight,max_w,word,index+1,max_index,flag)) return true;
            flag[height][wight] = 0;
        }

        return false;
    }
}

 

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