力扣題目地址:https://leetcode-cn.com/problems/max-area-of-island/
首先看題目:
給定一個包含了一些 0 和 1的非空二維數組 grid , 一個 島嶼 是由四個方向 (水平或垂直) 的 1 (代表土地) 構成的組合。你可以假設二維矩陣的四個邊緣都被水包圍着。
找到給定的二維數組中最大的島嶼面積。(如果沒有島嶼,則返回面積爲0。)
示例:
示例 1:
[[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]
對於上面這個給定矩陣應返回 6。注意答案不應該是11,因爲島嶼只能包含水平或垂直的四個方向的‘1’。
示例 2:
[[0,0,0,0,0,0,0,0]]
對於上面這個給定的矩陣, 返回 0。
注意: 給定的矩陣grid 的長度和寬度都不超過 50。
解決思路:
這道題目用到了深度優先搜索算法,我感覺還是比較有難度的。一開始我也不會,只能去求助題解了。看完官方和幾個精選題解之後,我有了大概的思路。首先我們我們要遍歷整個二維數組,因爲我們要找出該二維數組中連續面積最大的島嶼。遍歷一個二維數組,我們需要用兩個for循環。然後在遍歷的過程中,如果遇到島嶼我們要使用遞歸不斷計算連續的島嶼面積:即該點爲1時;我們需要搜索我們的四周有沒有連着的島嶼,每次探索到一個點時,我們將該點的值設置爲1,這樣就不會重複探索,保證算法不會陷入死循環。
- 兩個for循環,遍歷整個二維數組
- 當遇到島嶼(x,y)時,向島嶼的四周探索(x+1,y),(x-1,y),(x,y+1),(x,y-1)
- 向四周探索完,如果還存在島嶼,需要重複步驟2,這裏就需要使用遞歸算法
- 每次遇到新的島嶼都會遞歸計算出島嶼的連續面積,我們每次和最大值比較,取大的放入最大值中,遍歷結束後,返回最大值。
代碼實現:
/**
* 求島嶼的最大面積,深度優先搜索法
* https://leetcode-cn.com/problems/max-area-of-island/
* @param grid
* @author Geyuxuan 2020-03-15 21:55:26
* @return int
*/
public int maxAreaOfIsland(int[][] grid) {
//存放最大島嶼值
int maxArea = 0;
//嵌套for循環,遍歷整個二維數組
for(int i = 0; i < grid.length; i++) {
for(int j = 0; j < grid[0].length; j++) {
//如果遇到新的陸地,計算該島嶼的連續面積
if(grid[i][j] == 1){
//遞歸計算島嶼連續面積
int area = getArea(grid,i,j);
//比較最大島嶼面積和當前島嶼面積,取最大值放入 maxArea
maxArea = maxArea > area ? maxArea : area;
}
}
}
//返回二維數組中的最大島嶼面積
return maxArea;
}
//遞歸算法,不斷探索上下左右的陸地
private int getArea(int[][] grid, int i, int j) {
//如果縱座標越界則返回面積0
if(i == grid.length || i < 0){
return 0;
}
//如果橫座標越界則返回面積0
else if(j == grid[0].length || j<0){
return 0;
}
//如果遇到陸地,將陸地變爲水(1->0),然後繼續探索四周
if(grid[i][j] == 1){
//將1值爲0,防止重複探索相同的陸地
grid[i][j] = 0;
//當前島嶼面積等於(1+下陸地的面積+上陸地面積+左陸地面積+右陸地面積)
return 1+getArea(grid,i+1,j)+getArea(grid,i-1,j)+getArea(grid,i,j+1)+getArea(grid, i, j-1);
}
return 0;
}
不忘初心,砥礪前行。