LeetCode-算法-島嶼的最大面積

力扣題目地址: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,這樣就不會重複探索,保證算法不會陷入死循環。

  1. 兩個for循環,遍歷整個二維數組
  2. 當遇到島嶼(x,y)時,向島嶼的四周探索(x+1,y),(x-1,y),(x,y+1),(x,y-1)
  3. 向四周探索完,如果還存在島嶼,需要重複步驟2,這裏就需要使用遞歸算法
  4. 每次遇到新的島嶼都會遞歸計算出島嶼的連續面積,我們每次和最大值比較,取大的放入最大值中,遍歷結束後,返回最大值。

代碼實現:

	/**
     * 求島嶼的最大面積,深度優先搜索法
     * 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;
    }

不忘初心,砥礪前行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章