我正在尝试按照众所周知的计数岛问题进行编程。
并没有给我预期的输出。我哪里错了? 我的假设是,如果0触摸第0行或列或矩阵的维度...它将不会被视为岛屿
这是我的代码
public class Matrix {
static int rowCount = 5;
static int columnCount = 4;
static int[][] matrix = { {1,1,1,1,1},
{1,0,0,0,1},
{1,1,1,1,1},
{1,1,1,0,1}
};
static boolean[][] visited = new boolean[rowCount][columnCount];
private static int countIslands = 0;
public static void main(String[] args) {
try{
for(int i=0; i<rowCount; i++){
for(int j=0; j<columnCount; j++){
if(matrix[i][j]==0){
checkZeros(matrix, i, j);
System.out.println("returned " + i + j);
}
}
}
System.out.println(visited);
}catch(Exception e){
}
System.out.println(countIslands);
}
private static void checkZeros(int[][] matrix2, int i, int j) {
boolean valueWithinLimits = withinLimits(i,j);
System.out.println("checking for " + i + j);
if(valueWithinLimits) && checkAlreadyVisited(i,j)){
if(matrix[i][j+1]==0){
checkZeros(matrix2, i, j+1);
}
if(matrix[i+1][j+1]==0){
checkZeros(matrix2, i+1, j+1);
}
if(matrix[i+1][j]==0){
checkZeros(matrix2, i+1, j);
}
if(matrix[i+1][j-1]==0){
checkZeros(matrix2, i-1, j-1);
}
visited[i][j] = true;
System.out.println("i reached here when ij are : " + i + j);
countIslands ++;
}
}
private static boolean checkAlreadyVisited(int i, int j) {
System.out.println("visited found for " + i + j);
return visited[i][j-1] || visited[i-1][j-1] || visited[i-1][j] || visited[i-1][j+1];
}
private static boolean withinLimits(int i, int j) {
return (i>0 && i<rowCount-1 && j>0 && j<columnCount-1);
}
}
答案 0 :(得分:3)
以下解决方案经过测试,可以完全正常使用
package com.divyanshu.island;
/**
* <b>Assumption 1 : 1 is Land, 0 is water.</b>
* <b>Assumption 2 : It is all water outside the matrix.</b>
*
* Instantiate IslandCounter by passing a m*n matrix.
* Method getIslandCount gives you the count of island formed.
*
* </br></br>Or</br></br>
*
* Method getIslandCount gives the count of all connected 1s in a m*n matrix with values in 1 or 0.
*/
public class IslandCounter {
private Integer[][] matrix;
public IslandCounter(Integer[][] matrix) {
this.matrix = matrix;
}
public int getIslandCount() {
int count = 0;
if (matrix == null || matrix.length == 0) {
return count;
}
Integer[][] tempMatrix = matrix.clone();
for (int i = 0; i < tempMatrix.length; i++) {
for (int j = 0; j < tempMatrix[i].length; j++) {
if (detectIsland(tempMatrix, false, i, j, matrix.length - 1, matrix[i].length - 1)) {
count++;
}
}
}
return count;
}
private boolean detectIsland(Integer[][] tempMatrix,
boolean islandDetected,
int i,
int j,
int iMax,
int jMax) {
if (i > iMax || j > jMax || i < 0 || j < 0 || tempMatrix[i][j] == 0) {
return islandDetected;
} else {
tempMatrix[i][j] = 0;
islandDetected = true;
detectIsland(tempMatrix, islandDetected, i - 1, j, iMax, jMax);
detectIsland(tempMatrix, islandDetected, i, j - 1, iMax, jMax);
detectIsland(tempMatrix, islandDetected, i + 1, j, iMax, jMax);
detectIsland(tempMatrix, islandDetected, i, j + 1, iMax, jMax);
}
return islandDetected;
}
}
===================================================================================
/**
*
*/
package com.divyanshu.island;
import java.util.Random;
/**
*This is a Main-Class to test the IslandCounter.
*/
public class IslandTest {
/**
* @param args
*/
public static void main(String[] args) {
Integer[][] matrix = generateMatrix();
printMatrix(matrix);
IslandCounter counter = new IslandCounter(matrix);
System.out.println("Total islands in the matrix : " + counter.getIslandCount());
}
private static Integer[][] generateMatrix() {
Integer[][] matrix = new Integer[4][4];
Random random = new Random();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = random.nextInt(2);
}
}
return matrix;
}
private static void printMatrix(Integer[][] matrix) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
}
答案 1 :(得分:0)
您可以做的是添加一个排除数组:一个零的元素数组。例如,如果您在限制范围内找到零,则可以开始四处查看是否存在任何零。继续寻找,直到找到所有这些。然后将这些零中的每一个添加到排除数组中,当您继续循环时,请确保它跳过排除数组中的元素。这不是代码,而是程序逻辑的概述。
答案 2 :(得分:0)
我认为您的代码存在多个问题。
您的visited
矩阵充满了假,这意味着checkAlreadyVisited
将始终返回false
。此外,我不明白为什么这个方法检查周围环境,看看是否访问了当前位置。使用像访问过的临时矩阵是一个好主意,但你应该打印两张地图以确保它有效。
countIslands
永远不会递增,但是一旦你解决了它,它就会在每次调用时递增(它应该匹配地图上的0的数量)。如果您希望他的解决方案使用边界约束,您必须在for循环之前在每个边框上应用他的detectIsland
。
1
并且不认为触及边界的岛屿不是岛屿(如你所说)。
要更正您的解决方案,visited
矩阵在使用前必须是matrix
的副本,checkAlreadyVisited
应该只扫描[i][j]
而不是其中的内容,而您每次通话时都不应增加countIslands
。
再次,在每个回合打印您的地图,并使用更简单的矩阵,如:
static int[][] matrix = {{1,1,1},
{1,0,1},
{1,1,1},};
(没看到这个问题是三个老人......无论如何,你走了)