首页 > 试题广场 >

矩阵中的路径

[编程题]矩阵中的路径
  • 热度指数:88925 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
数据范围:,
示例1

输入

[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcced"

输出

true
示例2

输入

[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcb"

输出

false

备注:
0 <= matrix.length <= 200
0 <= matrix[i].length <= 200
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param matrix char字符型二维数组
     * @param word string字符串
     * @return bool布尔型
     */
    public boolean hasPath (char[][] matrix, String word) {
        int m = matrix.length;
        int n = matrix[0].length;
        if (m == 0 || n == 0) return false;

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (backTrack(matrix, word, i, j, 0)) {
                    return true;
                }
            }
        }
        return false;
    }

    HashSet<String> visited = new HashSet<>();
    private boolean backTrack(char[][] matrix, String word, int i, int j, int idx) {
        if (i < 0 || j < 0 || i >= matrix.length || j >= matrix[0].length ||
                visited.contains(String.valueOf(i) + "," + String.valueOf(j))) {
            return false;
        }

        if (matrix[i][j] != word.charAt(idx)) {
            return false;
        }

        if (idx >= word.length()-1) {
            return true;
        }

        visited.add(String.valueOf(i) + "," + String.valueOf(j));
        boolean up = backTrack(matrix, word, i - 1, j, idx + 1);
        boolean down = backTrack(matrix, word, i + 1, j, idx + 1);
        boolean left = backTrack(matrix, word, i, j - 1, idx + 1);
        boolean right = backTrack(matrix, word, i, j + 1, idx + 1);
        visited.remove(String.valueOf(i) + "," + String.valueOf(j));

        return up || down || left || right;
    }
}

发表于 2024-08-06 15:44:21 回复(0)
回溯
    public boolean hasPath (char[][] matrix, String word) {
        int x = 0;int y = 0;
        iscan = false;
        char[] wors = word.toCharArray();
        for (int i = 0; i < matrix.length; i++) {
            x = i;
            for (int j = 0; j < matrix[0].length; j++) {
                if (iscan)break;
                if (matrix[i][j] == wors[0]) {
                    y = j;
                    isused=new boolean[matrix.length][matrix[0].length];
                    back(0, x, y, matrix, wors);
                }
            }
            if (iscan) break;
        }
        return iscan;
    }
    public static boolean iscan;
    public static boolean[][] isused;
    public static void back(int n, int x, int y, char[][] matrix, char[] wors) {
        if (n == wors.length || iscan) {
            iscan = true;
            return;
        }
        for (int i = 0; i < 4; i++) {
            if (x >= matrix.length || x < 0 || y >= matrix[0].length || y < 0) return;
            if (matrix[x][y] != wors[n]||isused[x][y]) return;
            isused[x][y]=true;
            int xs = 0; int ys = 0;
            switch (i) {
                case 0:xs =-1;break;
                case 1:xs = 1;break;
                case 2:ys = 1;break;
                case 3:ys =-1;break;
            }
            back(n + 1, x + xs, y + ys, matrix, wors);
            isused[x][y]=false;
        }
    }


发表于 2023-09-18 10:33:04 回复(0)
import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param matrix char字符型二维数组
     * @param word string字符串
     * @return bool布尔型
     */
    static boolean flag = false;
    boolean[][] used;
    public boolean hasPath (char[][] matrix, String word) {
        // write code here
        used = new boolean[matrix.length][matrix[0].length];
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (!flag) {
                    process(matrix, word, "", 0, i, j);
                }
            }
        }
        return flag;
    }
    public void process(char[][] matrix, String word, String cur, int num, int i,
                        int j) {
        if (i < 0 || j < 0 || i == matrix.length || j == matrix[0].length) {
            return;
        }
        if (!flag && num == word.length()) {
            if (cur.equals(word)) {
                flag = true;
            }
            return;
        }
        if (!flag && !used[i][j] && matrix[i][j] == word.charAt(num)) {
            used[i][j] = true;
            cur += matrix[i][j];
            if (cur.equals(word)) {
                flag = true;
            }
            process(matrix, word, cur, num + 1, i + 1, j);
            process(matrix, word, cur, num + 1, i - 1, j);
            process(matrix, word, cur, num + 1, i, j + 1);
            process(matrix, word, cur, num + 1, i, j - 1);
            used[i][j] = false;
        }
    }
}
发表于 2023-03-25 12:25:55 回复(0)
//经典的递归问题,类似问题可以看LeetCode 全排列问题 讲的很详细 或者岛屿问题
public class Solution {
    public boolean ans = false;
    public boolean hasPath (char[][] matrixString word) {
        boolean[][] state = new boolean[matrix.length][matrix[0].length];
        int length = word.length();
        String str = "";
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                recursion(matrix, word, str, length, 0, state, i, j, 0);
                if (ans) {
                    return true;
                }
            }
        }
        return false;
    }
    public void recursion(char[][] matrixString wordString strint length,
                          int indexboolean[][] stateint iint jint l) {
        if (index == length) {
            if (str.equals(word)) {
                ans = true;
            }
            return;
        }
        if (i < 0 || i >= matrix.length) {
            return;
        }
        if (j < 0 || j >= matrix[0].length) {
            return;
        }
        if (!state[i][j]) {
            if (matrix[i][j] == word.charAt(l)) {
                state[i][j] = true;
                recursion(matrix, word, str + matrix[i][j], length, index + 1, state, i + 1, j,
                          l + 1);
                recursion(matrix, word, str + matrix[i][j], length, index + 1, state, i - 1, j,
                          l + 1);
                recursion(matrix, word, str + matrix[i][j], length, index + 1, state, i, j + 1,
                          l + 1);
                recursion(matrix, word, str + matrix[i][j], length, index + 1, state, i, j - 1,
                          l + 1);
                state[i][j] = false;
            }
        }
    }
}

发表于 2022-10-15 23:22:08 回复(0)
通过全部用例,23ms,11112kb
 //记录word首字母每次出现时和坐标的对应关系,string的第一位是横坐标,第二位是纵坐标
    HashMap<Integer, String> map = new HashMap<>();
    //word首字母在矩阵中出现的次数
    int times = 0;
    public boolean hasPath (char[][] matrix, String word) {
        // write code here
        Boolean result = false;
        //成功的次数
//         int success = 0;
        if (matrix == null || matrix.length == 0) {
            result = false;
        }
        int n = matrix.length;
        int m = matrix[0].length;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (matrix[i][j] == word.charAt(0)) {
                    times++;
                    map.put(times, i + "," + j);
                }
            }
        }
        //按照word首字母出现的次数,依次重新开始规划路线
        for (int t = 1; t <= times; t++) {
            String[] strs = map.get(t).split(",");
//             System.out.println(t + "======");
//             System.out.println("times="+times);
            int x = Integer.parseInt(strs[0]);
            int y = Integer.parseInt(strs[1]);
//             System.out.println("===" + x + "===" + y);
            int k = 0;
            //初始化flag矩阵记录是否走过
            Boolean[][] flag = new Boolean[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    flag[i][j] = false;
                }
            }
            for (int i = x; i < n; i++) {
                for (int j = y; j < m; j++) {
                    if (dfs(matrix, n, m, i, j, word, k, flag)) {
                        result = true;
                    }
                }
            }
//             System.out.println("");
//             System.out.println("");
            //如果返回结果为true,即已经找到完整路径,给本次循环也输出true
            if (result == true) {
//                 success+=1;
//                 System.out.println("true"+"第"+t+"次循环时成功,"+"共成功"+success+"次!");
                break;
            }
        }
        return result;
    }

    private boolean dfs(char[][] matrix, int n, int m, int i, int j, String word, int k, Boolean[][] flag) {
        //判断二维数组坐标是否与字符串当前下标的字符相等并且二维数组坐标是否为false(未使用)
        if (k >= word.length()) {
//            for(int )
            return true;
        }
        if (i < 0 || i >= n || j < 0 || j >= m) {
            return false;
        }
//         System.out.println(k + "===" + word.charAt(k));
//         System.out.println(i + "+++" + j + matrix[i][j]);


        //当某个节点有多条路径时执行的方法
        if (matrix[i][j] == word.charAt(k) && !flag[i][j]) {
            flag[i][j] = true;
            //验证当前节点是否有多个下一步,并记录当前状态下的i,j,k,flag,times状态
            Boolean[] result = new Boolean[4];
            result[0] =dfs(matrix, n, m, i - 1, j, word, k + 1, flag);
            result[1] =dfs(matrix, n, m, i + 1, j, word, k + 1, flag);
            result[2] =dfs(matrix, n, m, i, j - 1, word, k + 1, flag);
            result[3] =dfs(matrix, n, m, i, j + 1, word, k + 1, flag);
            if (result[0]||result[1]||result[2]||result[3]) {
                return true;
            }
        }
        flag[i][j] = false;
        return false;
    }

发表于 2022-09-02 14:19:22 回复(0)

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix char字符型二维数组 
     * @param word string字符串 
     * @return bool布尔型
     */
    public boolean hasPath (char[][] matrix, String word) {
        // write code here
        if(matrix==null||matrix.length==0)
            return false;
        int m=matrix.length;
        int n=matrix[0].length;
        boolean flag[][]=new boolean[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]==word.charAt(0)){//找到开头结点
                   if( dfs(matrix,word,i,j,0,flag)){//如果为true 表示找到了这个路径
                       return true;
                   }
                //那么这次没找到,也说不定会存在其他路径
                }
            }
        }
        return false;
    }
            public  boolean dfs(char[][] matrix, String word, int i, int j, int index, boolean[][] flag) {
            //index记录word字符串的下标
            if (i >= matrix.length || i < 0 || j >= matrix[0].length || j < 0) {//数组越界
                return false;
            }
            if (flag[i][j]) {//元素已经在路径里面了
                return false;
            }
            if (matrix[i][j] == word.charAt(index)) {//如果说元素相等,表示可以继续递归
                flag[i][j] = true;
                 if (index == word.length()-1) {//表示word字符串已经遍历结束了
                return true;
                   }
                //深度遍历
                if (dfs(matrix, word, i, j + 1, index + 1, flag) ||
                        dfs(matrix, word, i, j - 1, index + 1, flag) ||
                        dfs(matrix, word, i + 1, j, index + 1, flag) ||
                        dfs(matrix, word, i - 1, j, index + 1, flag))
                    return true;
                //如果深度遍历结果是false,那么回溯
                flag[i][j] = false;
                return false;
            } else
                return false;//元素不相等 返回false
        }
}

发表于 2022-08-31 09:58:44 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix char字符型二维数组 
     * @param word string字符串 
     * @return bool布尔型
     */
    char[] arr;
    int[][] log;
    int len;// 相当于x
    int len2; //相当于y
    public boolean hasPath (char[][] matrix, String word) {
        // write code here
        if(word.equals("")){
            return false;
        }
        arr=word.toCharArray();
        len=matrix[0].length;
        len2=matrix.length;
        log=new int[len2][len];
        for(int i=0;i<len2;i++){
            for(int j=0;j<len;j++){
                if(matrix[i][j]==arr[0]){
                   // log[i][j]=1;
                    boolean flag=choose(i,j,matrix,0);
                    if(flag){
                        return true;
                    }
                    //log[i][j]=0;
                }
                
            }
        }
        return false;
    }
    
    public boolean choose(int y,int x,char[][] matrix,int index){
        if(index>=arr.length){
            return true;
        }
                //看边界
        if(y<0||y>=len2){
            return false;
        }else if(x<0||x>=len){
            return false;
        }
         if(log[y][x]==1){
             return false;
         }

        if(matrix[y][x]==arr[index]&&log[y][x]==0){
            log[y][x]=1;    //说明使用了
            //说明找到
            boolean flag=choose(y-1,x,matrix,index+1)||choose(y+1,x,matrix,index+1)
                ||choose(y,x+1,matrix,index+1)||choose(y,x-1,matrix,index+1);
            if(flag){
                return true;
            }
            log[y][x]=0;
        }
        return false;
        
    }
}

发表于 2022-08-05 22:50:28 回复(0)
两次for回溯,也同时是在找初始位置

设置一个boolean v[][]来看看是否被访问过,如果i,j超界或v[i][j]被访问过,则失败
如果值匹配成功,且s到达word.length()-1,则成功

当一个值martix和word匹配成功后,v[i][j]=true。然后去看上,下,左,右的dfs(s+1)是否匹配成功,成功则返回true。失败则说明匹配不上,回溯,v[i][j]=false,就当自己没来过。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix char字符型二维数组 
     * @param word string字符串 
     * @return bool布尔型
     */
    public boolean hasPath (char[][] matrix, String word) {
        // write code here
        //dfs+回溯
        //回溯都需要for循环,同时遍历找word.charAt(0)出现的位置
        for(int i = 0; i < matrix.length; i++){
            for(int j = 0; j < matrix[0].length; j++){
                //每次创建新的访问数组,一次回溯可以得到当前的结果
                boolean[][] v = new boolean[matrix.length][matrix[0].length];  
                //0代表从word的第一个开始匹配
                if(dfs(i, j, matrix, v, 0, word)) return true;
            }
        }
        return false;
    }
    
    public boolean dfs(int i, int j, char[][] matrix, boolean[][] v, int s, String word){
        //如果i,j超出范围;v[i][j]已被访问,失败
        if(i<0||i>=matrix.length||j<0||j>=matrix[0].length||v[i][j]==true) return false;
        //如果匹配成功,成功
        if(matrix[i][j]==word.charAt(s)&&s==word.length()-1) return true;
        //匹配,回溯
        if(matrix[i][j]==word.charAt(s)){
            v[i][j] = true;
            if(dfs(i-1,j,matrix,v,s+1,word)||dfs(i+1,j,matrix,v,s+1,word)||dfs(i,j-1,matrix,v,s+1,word)||dfs(i,j+1,matrix,v,s+1,word)){
                return true;
            }
        }
        //如果下一个找不到,就当自己没来过,退回去。
        //并且如果不匹配,直接结束
        v[i][j] = false;
        return false;
    }
    
}


发表于 2022-07-04 22:28:52 回复(1)
 public boolean hasPath (char[][] matrix, String word) {
        char[] cc = word.toCharArray();
        int row = matrix.length;
        int col = matrix[0].length;
        boolean[][] isVisited = new boolean[row][col];
        for(int i = 0 ; i < row ; i ++) {
            for(int j = 0 ; j < col ; j ++) {
                int k = 0;
               if(matrix[i][j] == cc[k]) {
                   if(dfs(matrix,cc,isVisited,i,j,k)) {
                       return true;
                   }
               }
            }
        }
        return false;
    }
    private boolean dfs(char[][] matrix,char[] cc , boolean[][] isVisited,int row,int col,int k) {
        if(row < 0 || row > matrix.length-1 || col < 0 || col > matrix[0].length-1 || isVisited[row][col] || matrix[row][col] != cc[k]) return false;
        if(k == cc.length - 1) return true;
        ++ k ;
        isVisited[row][col] = true;
        if(dfs(matrix,cc,isVisited,row+1,col,k) || dfs(matrix,cc,isVisited,row-1,col,k) || dfs(matrix,cc,isVisited,row,col+1,k)
            || dfs(matrix,cc,isVisited,row,col-1,k)){
            return true ;
        }
        isVisited[row][col] = false;
        return false ;
    }

发表于 2022-06-02 17:15:24 回复(0)
JAVA  回溯   
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param matrix char字符型二维数组
     * @param word string字符串
     * @return bool布尔型
     */
    private boolean[][] way_flag;    //false就是可以走   true就是已经走过了,不能再走
    private boolean res = false;
    private final int[][] WAY = {{0, 1}, {-1, 0}, {0, -1}, {1, 0}};


    public boolean hasPath(char[][] matrix, String word) {
        // write code here
        int x = matrix.length;
        int y = matrix[0].length;
        way_flag = new boolean[x][y];
        char[] chars = word.toCharArray();
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                dfs(i, j, 0, matrix, chars);
            }
        }
        return res;

    }

    public void dfs(int s_x, int s_y, int locate, char[][] matrix, char[] word) {

        if (locate == word.length - 1) {
            if (word[locate] == matrix[s_x][s_y]) {
                res = true;
            }
            return;
        }

        if (word[locate] == matrix[s_x][s_y]) {
            for (int i = 0; i < WAY.length; i++) {
                int new_x = s_x + WAY[i][0];
                int new_y = s_y + WAY[i][1];
                if (isWay(new_x, new_y)) {
                    if (!way_flag[new_x][new_y]) {
                        way_flag[new_x][new_y] = true;
                        dfs(new_x, new_y, locate + 1, matrix, word);
                        way_flag[new_x][new_y] = false;
                    }
                }
            }

        } else {
            return;
        }

    }

    public boolean isWay(int x, int y) {
        int bor_x = way_flag.length;
        int bor_y = way_flag[0].length;
        if (0 <= x && x < bor_x && 0 <= y && y < bor_y) {
            return true;
        } else {
            return false;
        }
    }
}


发表于 2022-05-31 16:17:40 回复(0)
signal[i][j] = 1;
        boolean a = walk(i,j-1,word,index+1,matrix,signal);
        boolean b = walk(i,j+1,word,index+1,matrix,signal);
        boolean c = walk(i-1,j,word,index+1,matrix,signal);
        boolean d = walk(i+1,j,word,index+1,matrix,signal);
        if (a|b|c|d == false){
            signal[i][j] = 0;
        }
需要注意在进行更深层次递归前要把visited_signal置1因为假设我们走了这一步则走过的位置不能走回来,但是如果深层次递归中没有可行的路径,那么说明这个假设步是错误的,我们不会真的选取它,因此visited_signal应当重新置0
发表于 2022-03-26 14:00:55 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix char字符型二维数组 
     * @param word string字符串 
     * @return bool布尔型
     */
    public boolean hasPath (char[][] matrix, String word) {
        // write code here
        char[] words = word.toCharArray();
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++)
                if (bfs(matrix, words, i, j, 0)) return true;
        }
        return false;
    }
    public boolean bfs (char[][] matrix, char[] words, int i, int j, int index) {
        if (i < 0 || i>=matrix.length || j < 0 || j >=matrix[0].length || matrix[i][j] != words[index])
            return false;
        char tmp = matrix[i][j];
        matrix[i][j] = '.';
        if (index == words.length-1) return true;
        boolean result =  bfs(matrix, words, i-1, j, index + 1) ||
            bfs(matrix, words, i+1, j, index + 1) ||
            bfs(matrix, words, i, j-1, index + 1) ||
            bfs(matrix, words, i, j+1, index + 1);
        matrix[i][j] = tmp;
        return result;
    }
}

发表于 2022-03-16 13:34:43 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix char字符型二维数组 
     * @param word string字符串 
     * @return bool布尔型
     */
    public boolean hasPath (char[][] matrix, String word) {
        // write code here
        for(int i=0;i<matrix.length;i++){
            for(int j=0;j<matrix[0].length;j++){
                if((matrix[i][j]==word.charAt(0)) 
                   && dfs(matrix,word,i,j,0)){
                    return true;
                }
            }
        }
        return false;
    }
    private boolean dfs(char[][] matrix, String word, int i,int j,int cur){
        if(word.length()==cur){
            return true;
        }
        if(i<0 || i>=matrix.length || j<0 || j>=matrix[0].length){
            return false;
        }
        if(matrix[i][j]!=word.charAt(cur) || matrix[i][j]=='0'){
            return false;
        }
        char temp = matrix[i][j];
        matrix[i][j] = '0';
        boolean flag = dfs(matrix,word,i-1,j,cur+1)
            || dfs(matrix,word,i+1,j,cur+1)
            || dfs(matrix,word,i,j-1,cur+1)
            || dfs(matrix,word,i,j+1,cur+1);
        matrix[i][j] = temp;
        return flag;
        
    }
}

发表于 2022-02-16 23:34:51 回复(0)
import java.util.*;
public class Solution {
    char[][] matrix;
    String word;
    public boolean hasPath (char[][] matrix, String word) {
        // 使用递归完成回溯
        this.matrix = matrix;
        this.word = word;
        // 对每个节点dfs
        for(int row=0;row<matrix.length;row++){
            for(int col=0;col<matrix[0].length;col++){
                // 一旦找到则直接返回
                if(recur(row,col,0)==true){
                    return true;
                }
            }
        }
        return false;
    }
    
    public boolean recur(int row, int col, int len){
        // 以当前坐标为起点,向四个方向递归搜索
        
        // 如果当前递归target长度==word长度,返回true
        if(len==word.length())
            return true;
        // 如果越界,返回false
        if(row<0 || col<0 || row>=matrix.length || col>=matrix[0].length)
            return false;
        // 如果当前坐标值==特殊值,说明往回找到了用过的点,返回false
        if(matrix[row][col]=='_')
            return false;
        // 如果当前坐标值不等于下一个需要的值,返回false
        if(matrix[row][col]!=word.charAt(len))
            return false;
        // 暂存当前值,以特殊值标记当前节点为“用过”
        char temp = matrix[row][col];
        matrix[row][col] = '_';
        // 如果到这一步还没终止递归,说明截至到现在是一路匹配下来的,继续向四个方向递归, 暂存当前结果
        boolean result = recur(row+1,col,len+1) || recur(row,col+1,len+1) || recur(row-1,col,len+1) || recur(row,col-1,len+1);
        // 恢复当前值
        matrix[row][col] = temp;
        // 返回结果
        return result;
    }
}

发表于 2022-01-11 23:00:36 回复(0)

问题信息

dfs
上传者:牛客301499号
难度:
37条回答 5080浏览

热门推荐

通过挑战的用户

查看代码
矩阵中的路径