题目描述
一个元素值要么0,要么1的矩阵,假设0是断路,1是通路,从左上角元素开始,向右或者向下走,走到右下角。判断能不能走到,如果能,路径长度是多少?
便利蜂开发岗3.20笔试第三道算法题
思路
这道题我百度居然没有找到现成的答案,逼着我自己想。
首先想到的是动态规划求最短路径
可以先将01矩阵中的所有0元素替换成一个超大的数(例如106),然后照搬动态规划求最短路径,如果路径大于106,说明没有通路。
但是这个方法也太别扭了,像睿智想出来的。
重新想的思路
这道题复杂度应该是比求最短路径要低的,因为只要碰到0就不往下走了,不用遍历矩阵每个元素。
另外,我发现一个01矩阵对角线路径的长度是固定的,要么没有通路,如果有通路的话,这个路径长度是定值,为(矩阵长度+矩阵宽度-2).
于是这道题就可以简化成判断有无通路就行了。
具体的解法
设最左上角元素坐标值为(0,0),往下、往左遍历每个元素,当前坐标值为(a,b),如果它的下边或者左边元素为1,从(a+1,b)或者(a,b+1)递归遍历这个小矩阵。
public static boolean findpath(int[][] matr,int startwid,int startdep) {
int wid = matr[0].length;
int dep = matr.length;
boolean hasdownpath = false,hasrightpath = false;
if(matr[startdep][startwid]==0) return false;
else if((wid-1==startwid)&&(dep-1==startdep)) return true;
if((dep-1>startdep) && matr[startdep+1][startwid]==1) hasdownpath = findpath(matr, startwid,startdep+1);
if((wid-1>startwid) && matr[startdep][startwid+1]==1) hasrightpath = findpath(matr, startwid+1, startdep);
return hasdownpath||hasrightpath;
}
判断完有没有通路,就可以计算路径长度了
public static int minDis(int wid, int dep) {
return wid+dep-2;
}
所以最终总的代码是
public class Main {
public static boolean findpath(int[][] matr,int startwid,int startdep) {
int wid = matr[0].length;
int dep = matr.length;
boolean hasdownpath = false,hasrightpath = false;
if(matr[startdep][startwid]==0) return false;
else if((wid-1==startwid)&&(dep-1==startdep)) return true;
if((dep-1>startdep) && matr[startdep+1][startwid]==1) hasdownpath = findpath(matr, startwid,startdep+1);
if((wid-1>startwid) && matr[startdep][startwid+1]==1) hasrightpath = findpath(matr, startwid+1, startdep);
return hasdownpath||hasrightpath;
}
public static int minDis(int wid, int dep) {
return wid+dep-2;
}
public static void main(String[] args) {
int[][] test = {{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,0}};
int dis = findpath(test,0,0)? minDis(test[0].length,test.length):0;
System.out.print(dis);
}
}