LeetCode 695 島嶼的最大面積
阿新 • • 發佈:2020-08-28
LeetCode 695 島嶼的最大面積
題目描述:
給定一個包含了一些 0 和 1 的非空二維陣列 grid 。
一個 島嶼 是由一些相鄰的 1 (代表土地) 構成的組合,這裡的「相鄰」要求兩個 1 必須在水平或者豎直方向上相鄰。你可以假設 grid 的四個邊緣都被 0(代表水)包圍著。
找到給定的二維陣列中最大的島嶼面積。(如果沒有島嶼,則返回面積為 0 。)
DFS(深度優先遍歷)
執行用時:4 ms, 在所有 Java 提交中擊敗了28.45%的使用者
記憶體消耗:40.4 MB, 在所有 Java 提交中擊敗了11.25%的使用者
class Solution { public int maxAreaOfIsland(int[][] grid) { //尋找圖中最大連通分量的個數 //每個連通分量使用DFS的方式完全標記 if(grid==null || grid.length==0 || grid[0].length==0) { return 0; } int[][] directs = new int[][]{ {0,1},{1,0},{0,-1},{-1,0} }; //已訪問的連通分量中的陸地使用'2'標記 int result = 0; for(int row=0; row<grid.length; row++) { for(int col=0; col<grid[0].length; col++) { if(grid[row][col]==1) { result = Math.max( result, dfs(grid, new int[]{row, col}, directs) ); } } } return result; } public int dfs(int[][] grid, int[] axis, int[][] directs) { /*本節點標記*/ int result = 1; grid[axis[0]][axis[1]] = 2; //已訪問 /*向下遞迴*/ for(int[] direct: directs) { int nextRow = axis[0] + direct[0]; int nextCol = axis[1] + direct[1]; /*剪枝: 不符合條件不向下遞迴*/ if(nextRow>=0 && nextRow<grid.length && nextCol>=0 && nextCol<grid[0].length && grid[nextRow][nextCol]==1) { result += dfs(grid, new int[]{nextRow, nextCol}, directs); } } /*返回結果*/ return result; } }
沉島思想優化
轉載於github題解
執行用時:2 ms, 在所有 Java 提交中擊敗了100.00%的使用者
記憶體消耗:40 MB, 在所有 Java 提交中擊敗了73.25%的使用者
class Solution { public int maxAreaOfIsland(int[][] grid) { int res = 0; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[i].length; j++) { if (grid[i][j] == 1) { res = Math.max(res, dfs(i, j, grid)); } } } return res; } // 每次呼叫的時候預設num為1,進入後判斷如果不是島嶼,則直接返回0,就可以避免預防錯誤的情況。 // 每次找到島嶼,則直接把找到的島嶼改成0,這是傳說中的沉島思想,就是遇到島嶼就把他和周圍的全部沉默。 // ps:如果能用沉島思想,那麼自然可以用朋友圈思想。有興趣的朋友可以去嘗試。 private int dfs(int i, int j, int[][] grid) { if (i < 0 || j < 0 || i >= grid.length || j >= grid[i].length || grid[i][j] == 0) { return 0; } grid[i][j] = 0; int num = 1; num += dfs(i + 1, j, grid); num += dfs(i - 1, j, grid); num += dfs(i, j + 1, grid); num += dfs(i, j - 1, grid); return num; } }