给你一个大小为 m x n 的二进制矩阵 grid 。
岛屿   是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上  相邻。你可以假设grid 的四个边缘都被 0(代表水)包围着。
岛屿的面积是岛上值为 1 的单元格的数目。
计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。
示例 1: 
**输入:** grid = [[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: 
**输入:** grid = [[0,0,0,0,0,0,0,0]]
**输出:** 0
提示: 
m == grid.lengthn == grid[i].length1 <= m, n <= 50grid[i][j] 为 0 或 1 
📺 视频题解 
📖 文字题解 方法一:深度优先搜索 算法 
我们想知道网格中每个连通形状的面积,然后取最大值。
如果我们在一个土地上,以 4 个方向探索与之相连的每一个土地(以及与这些土地相连的土地),那么探索过的土地总数将是该连通形状的面积。
为了确保每个土地访问不超过一次,我们每次经过一块土地时,将这块土地的值置为 0。这样我们就不会多次访问同一土地。
 
[sol1-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class  Solution :    def  dfs (self, grid, cur_i, cur_j ) -> int :         if  cur_i < 0  or  cur_j < 0  or  cur_i == len (grid) or  cur_j == len (grid[0 ]) or  grid[cur_i][cur_j] != 1 :             return  0          grid[cur_i][cur_j] = 0          ans = 1          for  di, dj in  [[0 , 1 ], [0 , -1 ], [1 , 0 ], [-1 , 0 ]]:             next_i, next_j = cur_i + di, cur_j + dj             ans += self.dfs(grid, next_i, next_j)         return  ans     def  maxAreaOfIsland (self, grid: List [List [int ]] ) -> int :         ans = 0          for  i, l in  enumerate (grid):             for  j, n in  enumerate (l):                 ans = max (self.dfs(grid, i, j), ans)         return  ans 
[sol1-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class  Solution  {    int  dfs (vector<vector<int >>& grid, int  cur_i, int  cur_j)           if  (cur_i < 0  || cur_j < 0  || cur_i == grid.size () || cur_j == grid[0 ].size () || grid[cur_i][cur_j] != 1 ) {             return  0 ;         }         grid[cur_i][cur_j] = 0 ;         int  di[4 ] = {0 , 0 , 1 , -1 };         int  dj[4 ] = {1 , -1 , 0 , 0 };         int  ans = 1 ;         for  (int  index = 0 ; index != 4 ; ++index) {             int  next_i = cur_i + di[index], next_j = cur_j + dj[index];             ans += dfs (grid, next_i, next_j);         }         return  ans;     } public :    int  maxAreaOfIsland (vector<vector<int >>& grid)           int  ans = 0 ;         for  (int  i = 0 ; i != grid.size (); ++i) {             for  (int  j = 0 ; j != grid[0 ].size (); ++j) {                 ans = max (ans, dfs (grid, i, j));             }         }         return  ans;     } }; 
[sol1-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class  Solution  {    public  int  maxAreaOfIsland (int [][] grid)  {         int  ans  =  0 ;         for  (int  i  =  0 ; i != grid.length; ++i) {             for  (int  j  =  0 ; j != grid[0 ].length; ++j) {                 ans = Math.max(ans, dfs(grid, i, j));             }         }         return  ans;     }     public  int  dfs (int [][] grid, int  cur_i, int  cur_j)  {         if  (cur_i < 0  || cur_j < 0  || cur_i == grid.length || cur_j == grid[0 ].length || grid[cur_i][cur_j] != 1 ) {             return  0 ;         }         grid[cur_i][cur_j] = 0 ;         int [] di = {0 , 0 , 1 , -1 };         int [] dj = {1 , -1 , 0 , 0 };         int  ans  =  1 ;         for  (int  index  =  0 ; index != 4 ; ++index) {             int  next_i  =  cur_i + di[index], next_j = cur_j + dj[index];             ans += dfs(grid, next_i, next_j);         }         return  ans;     } } 
复杂度分析 
方法二:深度优先搜索 + 栈 算法 
我们可以用栈来实现深度优先搜索算法。这种方法本质与方法一相同,唯一的区别是:
方法一通过函数的调用来表示接下来想要遍历哪些土地,让下一层函数来访问这些土地。而方法二把接下来想要遍历的土地放在栈里,然后在取出这些土地的时候访问它们。
访问每一片土地时,我们将对围绕它四个方向进行探索,找到还未访问的土地,加入到栈 stack 中;
另外,只要栈 stack 不为空,就说明我们还有土地待访问,那么就从栈中取出一个元素并访问。
 
[sol2-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class  Solution :    def  maxAreaOfIsland (self, grid: List [List [int ]] ) -> int :         ans = 0          for  i, l in  enumerate (grid):             for  j, n in  enumerate (l):                 cur = 0                  stack = [(i, j)]                 while  stack:                     cur_i, cur_j = stack.pop()                     if  cur_i < 0  or  cur_j < 0  or  cur_i == len (grid) or  cur_j == len (grid[0 ]) or  grid[cur_i][cur_j] != 1 :                         continue                      cur += 1                      grid[cur_i][cur_j] = 0                      for  di, dj in  [[0 , 1 ], [0 , -1 ], [1 , 0 ], [-1 , 0 ]]:                         next_i, next_j = cur_i + di, cur_j + dj                         stack.append((next_i, next_j))                 ans = max (ans, cur)         return  ans 
[sol2-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class  Solution  {public :    int  maxAreaOfIsland (vector<vector<int >>& grid)           int  ans = 0 ;         for  (int  i = 0 ; i != grid.size (); ++i) {             for  (int  j = 0 ; j != grid[0 ].size (); ++j) {                 int  cur = 0 ;                 stack<int > stacki;                 stack<int > stackj;                 stacki.push (i);                 stackj.push (j);                 while  (!stacki.empty ()) {                     int  cur_i = stacki.top (), cur_j = stackj.top ();                     stacki.pop ();                     stackj.pop ();                     if  (cur_i < 0  || cur_j < 0  || cur_i == grid.size () || cur_j == grid[0 ].size () || grid[cur_i][cur_j] != 1 ) {                         continue ;                     }                     ++cur;                     grid[cur_i][cur_j] = 0 ;                     int  di[4 ] = {0 , 0 , 1 , -1 };                     int  dj[4 ] = {1 , -1 , 0 , 0 };                     for  (int  index = 0 ; index != 4 ; ++index) {                         int  next_i = cur_i + di[index], next_j = cur_j + dj[index];                         stacki.push (next_i);                         stackj.push (next_j);                     }                 }                 ans = max (ans, cur);             }         }         return  ans;     } }; 
[sol2-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class  Solution  {    public  int  maxAreaOfIsland (int [][] grid)  {         int  ans  =  0 ;         for  (int  i  =  0 ; i != grid.length; ++i) {             for  (int  j  =  0 ; j != grid[0 ].length; ++j) {                 int  cur  =  0 ;                 Deque<Integer> stacki = new  LinkedList <Integer>();                 Deque<Integer> stackj = new  LinkedList <Integer>();                 stacki.push(i);                 stackj.push(j);                 while  (!stacki.isEmpty()) {                     int  cur_i  =  stacki.pop(), cur_j = stackj.pop();                     if  (cur_i < 0  || cur_j < 0  || cur_i == grid.length || cur_j == grid[0 ].length || grid[cur_i][cur_j] != 1 ) {                         continue ;                     }                     ++cur;                     grid[cur_i][cur_j] = 0 ;                     int [] di = {0 , 0 , 1 , -1 };                     int [] dj = {1 , -1 , 0 , 0 };                     for  (int  index  =  0 ; index != 4 ; ++index) {                         int  next_i  =  cur_i + di[index], next_j = cur_j + dj[index];                         stacki.push(next_i);                         stackj.push(next_j);                     }                 }                 ans = Math.max(ans, cur);             }         }         return  ans;     } } 
复杂度分析 
方法三:广度优先搜索 算法 
我们把方法二中的栈改为队列,每次从队首取出土地,并将接下来想要遍历的土地放在队尾,就实现了广度优先搜索算法。
[sol3-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class  Solution :    def  maxAreaOfIsland (self, grid: List [List [int ]] ) -> int :         ans = 0          for  i, l in  enumerate (grid):             for  j, n in  enumerate (l):                 cur = 0                  q = collections.deque([(i, j)])                 while  q:                     cur_i, cur_j = q.popleft()                     if  cur_i < 0  or  cur_j < 0  or  cur_i == len (grid) or  cur_j == len (grid[0 ]) or  grid[cur_i][cur_j] != 1 :                         continue                      cur += 1                      grid[cur_i][cur_j] = 0                      for  di, dj in  [[0 , 1 ], [0 , -1 ], [1 , 0 ], [-1 , 0 ]]:                         next_i, next_j = cur_i + di, cur_j + dj                         q.append((next_i, next_j))                 ans = max (ans, cur)         return  ans 
[sol3-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class  Solution  {public :    int  maxAreaOfIsland (vector<vector<int >>& grid)           int  ans = 0 ;         for  (int  i = 0 ; i != grid.size (); ++i) {             for  (int  j = 0 ; j != grid[0 ].size (); ++j) {                 int  cur = 0 ;                 queue<int > queuei;                 queue<int > queuej;                 queuei.push (i);                 queuej.push (j);                 while  (!queuei.empty ()) {                     int  cur_i = queuei.front (), cur_j = queuej.front ();                     queuei.pop ();                     queuej.pop ();                     if  (cur_i < 0  || cur_j < 0  || cur_i == grid.size () || cur_j == grid[0 ].size () || grid[cur_i][cur_j] != 1 ) {                         continue ;                     }                     ++cur;                     grid[cur_i][cur_j] = 0 ;                     int  di[4 ] = {0 , 0 , 1 , -1 };                     int  dj[4 ] = {1 , -1 , 0 , 0 };                     for  (int  index = 0 ; index != 4 ; ++index) {                         int  next_i = cur_i + di[index], next_j = cur_j + dj[index];                         queuei.push (next_i);                         queuej.push (next_j);                     }                 }                 ans = max (ans, cur);             }         }         return  ans;     } }; 
[sol3-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class  Solution  {    public  int  maxAreaOfIsland (int [][] grid)  {         int  ans  =  0 ;         for  (int  i  =  0 ; i != grid.length; ++i) {             for  (int  j  =  0 ; j != grid[0 ].length; ++j) {                 int  cur  =  0 ;                 Queue<Integer> queuei = new  LinkedList <Integer>();                 Queue<Integer> queuej = new  LinkedList <Integer>();                 queuei.offer(i);                 queuej.offer(j);                 while  (!queuei.isEmpty()) {                     int  cur_i  =  queuei.poll(), cur_j = queuej.poll();                     if  (cur_i < 0  || cur_j < 0  || cur_i == grid.length || cur_j == grid[0 ].length || grid[cur_i][cur_j] != 1 ) {                         continue ;                     }                     ++cur;                     grid[cur_i][cur_j] = 0 ;                     int [] di = {0 , 0 , 1 , -1 };                     int [] dj = {1 , -1 , 0 , 0 };                     for  (int  index  =  0 ; index != 4 ; ++index) {                         int  next_i  =  cur_i + di[index], next_j = cur_j + dj[index];                         queuei.offer(next_i);                         queuej.offer(next_j);                     }                 }                 ans = Math.max(ans, cur);             }         }         return  ans;     } } 
复杂度分析