题目如下
输入M*N的矩阵
0 0 1 1
1 0 1 1
0 0 1 0
0表示水
1表示小岛
把所有连在一起(上下左右相连)的1的和算出来,并把原来的1替换掉
输出M*N的矩阵
0 0 5 5
1 0 5 5
0 0 5 0
一眼看过去很简单,但是我在面试过程中,一个双层循环之后,就不知道该干啥了。后面搜了一下leetcode, 原题是https://leetcode-cn.com/problems/number-of-islands/,这道题是它的改版。
看了一下leetcode的官方题解,使用深度优先搜索可以很快解决这道题,但是这道题又麻烦在,不仅需要找岛屿,还需要求和,并输出一个二维数组,看了一下网络上目前还没有题解,应该是最新的题。
代码如下
public class Main {
public static void dfs(int[][] array, int i, int j, List<Map<Integer, Integer>> index){
//当越界和等于0终止寻找
if(i > array.length - 1 || i < 0 || j > array[0].length - 1 || j < 0 || array[i][j] == 0)
return;
//当前元素置为0,避免重复寻找
array[i][j] = 0;
Map<Integer, Integer> map = new HashMap<>();
map.put(i, j);
index.add(map);
//上下左右进行寻找
dfs(array, i - 1, j, index);
dfs(array, i + 1, j, index);
dfs(array, i, j + 1, index);
dfs(array, i, j - 1, index);
}
public static int[][] numIslands(int[][] array){
//用来存储坐标系
List<Map<Integer, Integer>> index = new ArrayList<>();
int[][] outPut = new int[array.length][array[0].length];
for (int i = 0; i < array.length; i++){
for (int j = 0; j < array[i].length; j++){
if(array[i][j] == 1){
dfs(array, i, j, index);
for (Map<Integer, Integer> map : index){
outPut[map.entrySet().stream().findFirst().get().getKey()][map.entrySet().stream().findFirst().get().getValue()] = index.size();
}
//重置
index.clear();;
}
}
}
return outPut;
}
public static void main(String[] args){
int[][] input = new int[][]{{0,0,1,1}, {1,0,1,1}, {0,0,1,0}};
int[][] output = numIslands(input);
}
}
欢迎大神拍砖,提供更加优雅的解法,算法小白瑟瑟发抖。
这里引用敖丙大佬的一句名言,知道的越多,不知道的越多。。。