給定乙個由'1'
(陸地)和'0'
(水)組成的的二維網格,計算島嶼的數量。乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。你可以假設網格的四個邊均被水包圍。
示例 1:
示例 2:輸入:
11110
11010
11000
00000
輸出: 1
思路是:對每乙個結點,採用bfs的方法,加入佇列,將有相連的點一一置零。但是時間複雜度比較高,對於比較大的二維陣列會超時。想起之前資料結構課上做的類似的問題,當時是用遞迴做的dfs的版本,嘗試實現一下。輸入:
11000
11000
00100
00011
輸出: 3
結果是超時,也難以計算時間複雜度和空間複雜度 。
看了官方題解,發現不用存入整個結構體,再迭代掃瞄,類似的二維陣列存入的問題,知道的網格結構的固定大小後,就可以固定row和col,只需要存入相對位置,就可以算出(i,j)。相對於上一次的版本,節省了大量建立新物件並插入佇列及遍歷佇列的時間,大幅度優化了時間複雜度,同時節省了point物件所需要的大量儲存空間,大幅度優化了空間複雜度,具體如下:public
intnumislands
(char
grid)
if(row==
0|| col==0)
return0;
// 針對單列或單行網格
if(row==
1||col==1)
if(row==1)
if(grid[0]
[col-1]
=='1'
) count++;}
else
if(grid[row-1]
[0]==
'1') count++;}
return count;
}else
else
if(b==col-1)
else
}else
if(a==row-1)
else
if(b==col-1)
else
}else
else
if(b==col-1)
else
}// 刪除當前陸地
grid[a]
[b]=
'0';
} count++;}
}}}return count;
}
時間複雜度:o(mxn) 取決於二維陣列的大小
空間複雜度:o(min(m,n)) 最壞條件下,即全為陸地的情況下的空間複雜度。
之前的廣度優先搜尋需要借助佇列來儲存待訪問的結點,這裡的深度優先搜尋利用了遞迴法回溯的特性,可以預設按照順序掃瞄訪問,但也要注意遞迴法也十分的消耗資源。public
intnumislands
(char
grid)
// <
if(c-
1>=
0&&grid[r]
[c-1]==
'1')
// >
if(c+
1[c+1]==
'1')
// v
if(r+
1[c]==
'1')}}
}}return count;
}
時間複雜度: o(mxn)
空間複雜度:o(mxn),最壞情況下,即全為陸地。
看了官方的題解,大概類似於遍歷一遍圖,找出所有的連通分支,然後統計連通分支數量(乙個孤立點也是乙個連通分支)。public
void
dfs(
char
grid,
int i,
int j)
// v
if(i+
1[j]==
'1')
// <
if(j-
1>=
0&&grid[i]
[j-1]==
'1')
// >
if(j+
1[j+1]==
'1')
}public
intnumislands
(char
grid)}}
return count;
}
按照這個思路,大概按照圖的連通分支演算法做一遍,之後再去看題解。
大概看了並查集的解釋後,發現這是乙個非常好的演算法,易於理解。但相對比較耗費資源。具體如下:
bfs演算法class
unionfind
// 秩為0,也就是樹的高度為零
rank[i * col + j]=0
;}}}
public
boolean
union
(int u,
int v)
count--
;return
true;}
public
intfind
(int u)
return u;}}
public
class
solution}}
}return unionfind.count;
}
dfs演算法
並查集演算法
在二維陣列的第二維陣列中元素個數固定後(網格),用 i*col+j 的方法代替 儲存 (i,j) 樣式的結構體(class實現)。可以大大減少建立新物件的資源開支。
在判斷鄰居是否連通時,為防止越界加上判斷就好,不用對每種情況都分析,要多總結,找到效率較高的方法。
LeetCode 200 島嶼數量
給定乙個由 1 陸地 和 0 水 組成的的二維網格,計算島嶼的數量。乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。你可以假設網格的四個邊均被水包圍。示例 1 輸入 11110 11010 11000 00000輸出 1 示例 2 輸入 11000 11000 00100 00...
leetcode200 島嶼數量
可以遍歷矩陣中的每個位置,如果遇到1就將與其相連的一片1都感染成2 dfs 並自增島數量。class solution object def numislands self,grid type grid list list str rtype int res 0 if not grid return...
leetcode 200 島嶼數量
給定乙個由 1 陸地 和 0 水 組成的的二維網格,計算島嶼的數量。乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。你可以假設網格的四個邊均被水包圍。示例 1 輸入 11110 11010 11000 00000 輸出 1思路 線性掃瞄整個二維網格,如果乙個結點包含 1,則以其...