你被请来给一个要举办高尔夫比赛的树林砍树. 树林由一个非负的二维数组表示, 在这个数组中:
0 表示障碍,无法触碰到.
1 表示可以行走的地面.
比1大的数 表示一颗允许走过的树的高度.
你被要求按照树的高度从低向高砍掉所有的树,每砍过一颗树,树的高度变为1。
你将从(0,0)点开始工作,你应该返回你砍完所有树需要走的最小步数。 如果你无法砍完所有的树,返回 -1 。
可以保证的是,没有两棵树的高度是相同的,并且至少有一颗树需要你砍。
示例 1:
输入:
[
[1,2,3],
[0,0,4],
[7,6,5]
]
输出: 6
示例 2:
输入:
[
[1,2,3],
[0,0,0],
[7,6,5]
]
输出: -1
示例 3:
输入:
[
[2,3,4],
[0,0,5],
[8,7,6]
]
输出: 6
解释: (0,0) 位置的树,你可以直接砍去,不用算步数
提示: 矩阵大小不会超过 50x50 。
思路:我是用的BFS过的这道题,当然,A*搜索做会更优!
class Solution {
private int num;
private int ans;
private boolean[][] flag;
private List<Integer> list;
private int[] dx= {1,-1,0,0};
private int[] dy= {0,0,-1,1};
class node{
int x,y,step,val;
public node(int x,int y,int step,int val) {
this.x=x;
this.y=y;
this.step=step;
this.val=val;
}
}
public int cutOffTree(List<List<Integer>> forest) {
int len=0;
int m=forest.size();
int n=forest.get(0).size();
num=0;
flag=new boolean[m][n];
ans=Integer.MAX_VALUE;
list=new ArrayList<>();
Queue<node> q=new LinkedList<>();
for(int i=0;i<m;i++)
for(int j=0;j<n;j++) {
if(forest.get(i).get(j)>1) {
num++;
list.add(forest.get(i).get(j));
}
}
if(num==0) return 0;
Collections.sort(list);
q.add(new node(0,0,0,forest.get(0).get(0)));
while(!q.isEmpty()) {
node now=q.poll();
if(now.val==list.get(len)) {
q.clear();
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
flag[i][j]=false;
len++;
}
if(len==num) return now.step;
for(int i=0;i<4;i++) {
int xx=now.x+dx[i];
int yy=now.y+dy[i];
if(xx<0 || xx>=m || yy<0 || yy>=n || forest.get(xx).get(yy)==0 || flag[xx][yy])
continue;
flag[xx][yy]=true;
q.add(new node(xx,yy,now.step+1,forest.get(xx).get(yy)));
}
}
return -1;
}
}