```
public class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;
int count = 0, m = grid.length, n = grid[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
dfs(grid, i, j, m, n);
count++;
}
}
}
return count;
}
private void dfs(char[][] grid, int row, int col, int m, int n) {
if (row < 0 || row >= m || col < 0 || col >= n) return;
if (grid[row][col] != '1') return;
grid[row][col] = 'M';
dfs(grid, row + 1, col, m, n);
dfs(grid, row - 1, col, m, n);
dfs(grid, row, col + 1, m, n);
dfs(grid, row, col - 1, m, n);
}
```

}

This problem is an example of either DFS or BFS. You can use the original array as a substitute of keeping a visited array. In the end, you can easily iterate through the input array again to change it back to its original if you are concerned with its integrity.