题解 | #矩阵中的路径#

矩阵中的路径

http://www.nowcoder.com/practice/2a49359695a544b8939c77358d29b7e6

     简单分享一下我对这个题的思路吧,本人学艺不精,如果有路过的大牛能帮助优化的话就更好了。
以本题示例为例:[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcced"
[a,b,c,e]
[s,f,c,s ]
[a,d,e,e]
     我们需要先再矩阵中找到头字符,在头字符的位置开始向四周遍历。 (刚开始没仔细看题,只从头开始,后来才发现)

     这里我写了一个find函数来查找,同时返回所有的i,j位置,如果使用map存储的话,可能会存在相同的i不同的j,造成记录位置失败,所以我使用了list存入字符串,在去除的时候再分开。
     在知道开始节点后,就要开始写递归求解,题目要求不能走重复了路径,所以这里我选择使用了一个flag矩阵来存储字母行走情况,为走过了打标记,只允许未被标记的进入下次递归求解。我在满足条件的情况下,即找到了符合条件的路径,在这里使用一个异常的特性,发生后直接中断本次递归,如果在主程序调用时,发生了这个异常,说明找到了解。(个人觉得用异常跳出递归的方式很好用,不仅解决了递归后续出口问题,还能减少递归运行的次数,不过不一定符合java写程序的标准)
     如果递归路径走到四周都没有满足情况的路,开始回退,并复原走过的flag矩阵数组,避免影响后续的路径。(这里我第一次没有考虑到,导致后续浪费很多时间)
到这里,这道题基本就结束了,恭候大佬批评指正。
import java.util.*;


public class Solution {
    public static boolean hasPath(char[][] matrix, String word) {
        if(matrix.length==0||matrix[0].length==0)
            return false;
        if(matrix.length==1){
            if(Arrays.toString(matrix[0]).contains(word))
                return true;
        }
        List<String> lt=find(matrix,word.charAt(0));
        if(lt.size()==0)
            return false;
        try {
            for (String s : lt) {
                String[] split = s.split(",");
                int i=Integer.parseInt(split[0]);
                int j=Integer.parseInt(split[1]);
                go(matrix,word,new boolean[matrix.length][matrix[0].length],i,j,0);
            }
        }catch (Exception e){
            return true;
        }
        return false;
    }
    public static int go(char[][] matrix, String word, boolean[][] flag, int i, int j, int index) throws Exception {//i,j为传入的头字母的位置,index为查找到word的第n位
        if(index==word.length()){
            throw new Exception("true");
        }
        if(flag[i][j]||matrix[i][j]!=word.charAt(index)){
            return -1;
        }
        if(matrix[i][j]==word.charAt(index)){
            flag[i][j]=true;
            if(j+1<matrix[0].length){
                if(go(matrix,word,flag,i,j+1,index+1)==-1)
                    flag[i][j+1]=false;//回退修改过的flag数组
            }
            if(j-1>=0){
                go(matrix,word,flag,i,j-1,index+1);
                flag[i][j-1]=false;//回退修改过的flag数组
            }
            if(i+1<matrix.length){
                go(matrix,word,flag,i+1,j,index+1);
                flag[i+1][j]=false;//回退修改过的flag数组
            }
            if(i-1>=0){
                go(matrix,word,flag,i-1,j,index+1);
                flag[i-1][j]=false;//回退修改过的flag数组
            }
        }
        return -1;
    }
    public static List<String> find(char[][] matrix,char c){//查找并返回全部某一个字节是在矩阵的位置
        List<String> lt=new ArrayList<>();
        int[] result={-1,-1};
        for (int i=0;i<matrix.length;i++){
            for (int j=0;j<matrix[0].length;j++){
                if (matrix[i][j]==c){
                    String s=""+i+","+j;//用","隔开,防止存在多位数的i和j如,11和12,不知道准确的i与j位数的情况
                    lt.add(s);
                }
            }
        }
        return lt;
    }
}
全部评论

相关推荐

Southyeung:我说一下我的看法(有冒犯实属抱歉):(1)简历不太美观,给我一种看都不想看的感觉,感觉字体还是排版问题;(2)numpy就一个基础包,机器学习算法是什么鬼?我感觉你把svm那些写上去都要好一点。(2)课程不要写,没人看,换成获奖经历;(3)项目太少了,至少2-3个,是在不行把网上学习的也写上去。
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
05-01 13:13
ecece:这么明目张胆虚报就业率啊
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务