剑指 Offer 12.矩阵中的路径

本文解析了如何使用深度优先搜索算法结合剪枝优化,解决字符矩阵中的路径查找问题,通过改进版代码展示了如何避免使用额外的book数组,利用board中的字符状态进行路径跟踪。时间复杂度为O(3^k * MN),空间复杂度为O(K)。
摘要由CSDN通过智能技术生成

剑指 Offer 12.矩阵中的路径

在这里插入图片描述
这题就是深度优先搜索加剪枝(搜到不是目标字符就返回),在搜索到正确字符时要记得return true,否则就会继续for循环,一直返回false。
基础版:

class Solution {
    int[][] next = new int[][]{{0,1},{1,0},{0,-1},{-1,0}};
    int[][] book;
    public boolean exist(char[][] board, String word) {
      book = new int[board.length][board[0].length];
      for(int i = 0; i < board.length; i++)
       for(int j = 0; j < board[0].length; j++) {
           book[i][j] = 0;
       }
      for(int i = 0; i < board.length; i++)
       for(int j = 0; j < board[0].length; j++) {
          if(board[i][j] == word.charAt(0)) {
              book[i][j] = 1;
              if(dfs(board, book, word, i, j, 1)) return true;
              book[i][j] = 0;
          }
       }
      return false;
    }

    public boolean dfs(char[][] board, int[][] book, String word,int x, int y, int step) {
       int tx,ty,k;
       if(step == word.length()) return true;
       for(k = 0; k <= 3; k++) {
          tx = x + next[k][0];
          ty = y + next[k][1];
         if(tx < 0 || tx > board.length - 1 || ty < 0 || ty > board[0].length - 1 || board[tx][ty] != word.charAt(step) ) continue;
         if(book[tx][ty] == 0)  {
             book[tx][ty] = 1;
            if(dfs(board, book, word, tx, ty, step+1)) return true;
             book[tx][ty] = 0;
         }
       }
        return false;
    }
}

改进版:
可以不使用book数组来标记已访问过的点,将board[x][y](已访问过的点)改为’\0’,它将不会和任何字符相等,回溯时再将它恢复成原来的字符word.charAt(step-1)。step-1为已比对过的字符。step为将要比对的字符。

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

    public boolean dfs(char[][] board, String word,int x, int y, int step) {
       int tx,ty,k;
       if(step == word.length()) return true;
       board[x][y] = '\0';
       for(k = 0; k <= 3; k++) {
          tx = x + next[k][0];
          ty = y + next[k][1];
         if(tx < 0 || tx > board.length - 1 || ty < 0 || ty > board[0].length - 1 || board[tx][ty] != word.charAt(step) ) continue;
         if(dfs(board, word, tx, ty, step+1)) return true;
       }
       board[x][y] = word.charAt(step-1);
        return false;
    }
}

在这里插入图片描述
时间复杂度O(3^k*MN)
: 最差情况下,需要遍历矩阵中长度为 KK字符串的所有方案,时间复杂度为 O(3^K),矩阵中共有 MN个起点,时间复杂度为 O(MN) 。
方案数计算: 设字符串长度为 K ,搜索中每个字符有上、下、左、右四个方向可以选择,舍弃回头(上个字符)的方向,剩下 3 种选择,因此方案数的复杂度为 O(3^K)。

空间复杂度 O(K) : 搜索过程中的递归深度不超过 K。


二刷

class Solution {
    public boolean exist(char[][] board, String word) {
      for(int i = 0; i < board.length; i++)
       for(int j = 0; j < board[0].length; j++) {
           if((board[i][j] == word.charAt(0))) {
              if(dfs(i, j, board, 0, word))
              return true;
           }
       }
       return false;
    }
    public boolean dfs(int i, int j, char[][] board, int word_index, String word) {
        
        if(i < 0 || j < 0 || i >= board.length || j >= board[0].length || board[i][j] != word.charAt(word_index)) return false;
        if(word_index == word.length() - 1) return true;
        char temp = board[i][j];
         board[i][j] = '\0';
         boolean res = dfs(i, j + 1, board, word_index + 1, word) || dfs(i + 1, j, board, word_index + 1, word) ||
        dfs(i, j - 1, board, word_index + 1, word) || dfs(i - 1, j, board, word_index + 1, word);
        board[i][j] = temp;
        return res;
    }
}

改用或的形式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值