题意:就是求 每个海洋到陆地的最短距离中的最长距离
最先想到的O(n^2*m)的方法:
把每一列的陆地纵坐标存到列表中
先从第一行开始
每次从左往右扫, 先计算自己这一点x到这一列所有陆地的距离d
然后再拿前面计算过的点x'到陆地的距离d', 再加上x- x',
即min(d, d' + x - x')
同理计算各行
还有从右往左再扫一遍
即可
class Solution {
int abs(int a, int b){
if(a > b){
return a -b;
}
else return b - a;
}
public int maxDistance(int[][] grid) {
int ylen = grid.length;
int xlen = grid[0].length;
Set<Integer>[] doors = new HashSet[xlen];
int doorsCount = 0;
for(int x = 0; x < xlen;x++){
doors[x] = new HashSet<>();
for(int y = 0; y < ylen;y++){
if(grid[y][x] == 1) {
doors[x].add(y);
doorsCount++;
}
}
}
if(doorsCount == 0 || xlen * ylen == doorsCount){
return -1;
}
int resultDis = Integer.MIN_VALUE;
List<Integer> moreDiss = new ArrayList<>();
int[][] minDis = new int[ylen][xlen];
for(int y=0;y<ylen;y++) {
moreDiss.clear();
//从左往右,计算最短距离
for (int x = 0; x < xlen; x++) {
int minnn = Integer.MAX_VALUE;
//横向距离已知
//找到当前一列有哪些陆地,计算当前列的最短距离
for (int doorY : doors[x]) {
if (abs(doorY, y) < minnn) {
minnn = abs(doorY, y);
}
}
for (int i = 0; i < x; i++) {
//之前几列的最短竖直距离已知, 横向距离也可直接计算
if (moreDiss.get(i) + (x - i) < minnn) {
minnn = moreDiss.get(i) + (x - i);
}
}
//保存
moreDiss.add(minnn);
minDis[y][x] = minnn;
}
moreDiss.clear();
//从右到左反向再来一遍
for (int x = xlen - 1; x >= 0; x--) {
int minnn = Integer.MAX_VALUE;
for (int doorY : doors[x]) {
if (abs(doorY, y) < minnn) {
minnn = abs(doorY, y);
}
}
for (int i = xlen - 1; i >= x+1; i--) {
if (moreDiss.get(xlen - 1 - i) + (i - x) < minnn) {
minnn = moreDiss.get(xlen - 1 - i) + (i - x);
}
}
moreDiss.add(minnn);
if (minnn < minDis[y][x]) {
minDis[y][x] = minnn;
}
//得到最短距离中的最长
if(grid[y][x] ==0 ){
if(minDis[y][x] > resultDis){
resultDis = minDis[y][x];
}
}
}
}
if(resultDis == Integer.MIN_VALUE){
return -1;
}
return resultDis;
}
}
时间如下,侥幸过了,只要不是O(m^2*n^2)就不会超: