岛问题
一个矩阵中只有0和1两种值,每个位置都可以和自己的上、下、左、右四个位置相连,如果有一片1连在一起,这个部分叫做一个岛。求一个矩阵中有多少个岛?
(注意是上下左右,斜着来不行)
这个问题有点类似于N皇后问题,我们采取的策略都是“感染”。我们遍历这个数组,一旦发现有1,那么我们就朝着其上下左右四个方向进行感染,然后递归进行这个操作。主要思路就是这样,现在我们来看看具体如何实现:
1 public static int countIslands(int[][] arr) { 2 if (arr == null || arr[0] == null) { 3 return 0; 4 } 5 int result = 0; 6 int row = arr.length; 7 int col = arr[0].length; 8 for (int i = 0; i < row; ++i) { 9 for (int j = 0; j < col; ++j) { 10 if (arr[i][j] == 1) { 11 ++result; 12 infect(arr, i, j, row, col); 13 } 14 } 15 } 16 return result; 17 }
这个是主要方法,首先是递归结束条件,这个很简单就不多说了。然后,是核心代码。遍历这个数组,一旦发现有一个数是1,立刻感染周围。
接下来我们来看看感染的代码:
1 private static void infect(int[][] arr, int i, int j, int row, int col) { 2 //i是行,j是列 3 if (i < 0 || i >= row || j < 0 || j >= col || arr[i][j] != 1) { 4 return; 5 } 6 arr[i][j] = 2; 7 infect(arr, i + 1, j, row, col); 8 infect(arr, i - 1, j, row, col); 9 infect(arr, i, j + 1, row, col); 10 infect(arr, i, j - 1, row, col); 11 }
感染的过程是一个递归的过程。在这里我们需要做的,首先就是判断是否是感染目标,数值为0的具有免疫功能,因此不能被感染。我们需要找到的就是数值为1的“易感染个体”。每找到一个1,我们就把它转化为2,然后让它继续感染周围为1的个体。当然,我们只能限定在这个范围内感染,否则是不行的。
来看看全部代码:
1 public class CountIslands { 2 public static int countIslands(int[][] arr) { 3 if (arr == null || arr[0] == null) { 4 return 0; 5 } 6 int result = 0; 7 int row = arr.length; 8 int col = arr[0].length; 9 for (int i = 0; i < row; ++i) { 10 for (int j = 0; j < col; ++j) { 11 if (arr[i][j] == 1) { 12 ++result; 13 infect(arr, i, j, row, col); 14 } 15 } 16 } 17 return result; 18 } 19 20 private static void infect(int[][] arr, int i, int j, int row, int col) { 21 //i是行,j是列 22 if (i < 0 || i >= row || j < 0 || j >= col || arr[i][j] != 1) { 23 return; 24 } 25 arr[i][j] = 2; 26 infect(arr, i + 1, j, row, col); 27 infect(arr, i - 1, j, row, col); 28 infect(arr, i, j + 1, row, col); 29 infect(arr, i, j - 1, row, col); 30 } 31 32 public static void main(String[] args) { 33 int[][] m = { 34 {0, 1, 1, 0, 1, 0, 0}, 35 {1, 1, 0, 0, 0, 1, 0}, 36 {0, 0, 1, 0, 0, 1, 1}, 37 {1, 0, 1, 0, 1, 0, 1}, 38 {0, 1, 1, 1, 0, 0, 0}, 39 {1, 1, 0, 0, 0, 1, 0}, 40 {0, 0, 1, 0, 0, 1, 0}, 41 }; 42 System.out.println("岛的数量:" + countIslands(m)); 43 } 44 }