思路:
從第一行往下對每個'1'分別對右和下相鄰爲'1'的元素做union操作,最後每個'1'都和上下左右四個相鄰的元素做了union,union and find count數即爲island數。
union and find:
有幾種實現,時間複雜度取決於find()以及union()函數,find()返回該節點屬於哪個集合,union把兩個節點對應的兩個集合進行歸併。
這裏採用最優的實現方式,find()函數搜索當前節點的根節點,union分別搜索兩個節點的根節點,並把小樹歸入大樹。
假設二維數組共有n個元素,時間複雜度爲O(nlogn)
/**
* Created by marsares on 15/6/21.
*/
public class NumberofIslands {
int row;
int column;
int count;
int[]index;
int[]sz;
public int numIslands(char[][] grid) {
if(grid==null)return 0;
row=grid.length;
if(row==0)return 0;
column=grid[0].length;
if(column==0)return 0;
index=new int[row*column];
sz=new int[row*column];
for(int i=0;i<index.length;i++){
index[i]=i;
if(grid[i/column][i%column]=='1')count++;
}
for(int i=0;i<sz.length;i++){
sz[i]=1;
}
for(int i=0;i<row;i++){
for(int j=0;j<column;j++){
if(i==row-1&&j==column-1)continue;
else if(i==row-1){
if(grid[i][j]=='1'&&grid[i][j+1]=='1')union(toIndex(i, j),toIndex(i, j + 1));
}
else if(j==column-1){
if(grid[i][j]=='1'&&grid[i+1][j]=='1')union(toIndex(i,j),toIndex(i+1,j));
}
else{
if(grid[i][j]=='1'&&grid[i][j+1]=='1')union(toIndex(i,j),toIndex(i,j+1));
if(grid[i][j]=='1'&&grid[i+1][j]=='1')union(toIndex(i,j),toIndex(i+1,j));
}
}
}
return count;
}
public int find(int i){
while(index[i]!=i){
i=index[i];
}
return i;
}
public void union(int a,int b){
int roota=find(a);
int rootb=find(b);
if(roota==rootb)return;
if(sz[roota]>sz[rootb])index[rootb]=roota;
else index[roota]=rootb;
count--;
}
private int toIndex(int i,int j){
return i*column+j;
}
public static void main(String[]args){
NumberofIslands noi=new NumberofIslands();
char[][]grid={{'1','1','0','0','0'},{'1','1','0','0','0'},{'0','0','1','0','0'},{'0','0','0','1','1'}};
System.out.println(noi.numIslands(grid));
}
}