🔥BEATS 💯 % 🎯 |✨SUPER EASY BEGINNERS 👏| JAVA | C | C++ | PYTHON| JAVASCRIPT | DART 
IntuitionThe problem requires us to find the size of the largest island in a grid after potentially converting one water cell (represented by 0) into land (repr

## Intuition
The problem requires us to find the size of the largest island in a grid after potentially converting one water cell (represented by `0`) into land (represented by `1`). My first thought is to identify all existing islands, calculate their sizes, and then evaluate how converting each water cell could connect these islands to form a larger island. This involves using depth-first search (DFS) to traverse and label the islands while tracking their sizes.

## Approach
1. **Identify Islands and Their Sizes**:
   - Use DFS to traverse the grid and assign unique IDs to each island while calculating their sizes.
   - Store the sizes of each island in a map (`islandSizes`) where the key is the island ID and the value is its size.

2. **Evaluate Potential Island Sizes**:
   - Iterate through each cell in the grid. For each water cell (`0`), check its four neighboring cells (up, down, left, right).
   - Use a set to track unique island IDs that are adjacent to the current water cell.
   - Calculate the potential size of the new island if this water cell were converted to land by summing up the sizes of all connected islands plus one for the current cell.

3. **Determine Maximum Island Size**:
   - Keep track of the maximum size found during these evaluations. If there are no islands, return `0`.

4. **Return Result**:
   - Finally, return the maximum island size calculated.

### Code Examples

```cpp []
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    int largestIsland(vector<vector<int>>& grid) {
        int n = grid.size();
        int islandId = 2; // Start island IDs from 2 (since 0 and 1 are already used)
        unordered_map<int, int> islandSizes; // Maps island ID to its size

        // Directions for moving up, right, down, and left
        vector<vector<int>> directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

        // Step 1: Assign unique IDs to each island and calculate their sizes
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    int size = dfs(grid, i, j, islandId);
                    islandSizes[islandId] = size;
                    islandId++;
                }
            }
        }

        // Step 2: Evaluate each 0 to see if changing it to 1 can connect islands
        int maxIslandSize = islandSizes.empty() ? 0 : max_element(islandSizes.begin(), islandSizes.end(), [](const auto& a, const auto& b) { return a.second < b.second; })->second;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0) {
                    unordered_set<int> connectedIslands;
                    int potentialSize = 1; // Start with the current cell being changed to 1

                    // Check all four directions
                    for (const auto& dir : directions) {
                        int ni = i + dir[0];
                        int nj = j + dir[1];

                        if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] > 1) {
                            connectedIslands.insert(grid[ni][nj]);
                        }
                    }

                    // Sum the sizes of connected islands
                    for (const auto& id : connectedIslands) {
                        potentialSize += islandSizes[id];
                    }

                    maxIslandSize = max(maxIslandSize, potentialSize);
                }
            }
        }

        return maxIslandSize;
    }

private:
    int dfs(vector<vector<int>>& grid, int x, int y, int islandId) {
        if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] != 1) {
            return 0;
        }

        grid[x][y] = islandId; // Mark the cell with the island ID
        int size = 1;

        // Directions for moving up, right, down, and left
        vector<vector<int>> directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
        
        for (const auto& dir : directions) {
            size += dfs(grid, x + dir[0], y + dir[1], islandId);
        }

        return size;
    }
};
```

```java []
import java.util.*;

class Solution {
    public int largestIsland(int[][] grid) {
        int n = grid.length;
        int islandId = 2; // Start island IDs from 2
        Map<Integer, Integer> islandSizes = new HashMap<>(); // Maps island ID to its size

        // Directions for moving up, right, down, and left
        int[][] directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

        // Step 1: Assign unique IDs to each island and calculate their sizes
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    int size = dfs(grid, i, j, islandId);
                    islandSizes.put(islandId++, size);
                }
            }
        }

        // Step 2: Evaluate each water cell to see if changing it to land can connect islands
        int maxIslandSize = Collections.max(islandSizes.values(), Integer::compareTo);

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0) {
                    Set<Integer> connectedIslands = new HashSet<>();
                    int potentialSize = 1; // Start with changing this water cell to land

                    // Check all four directions
                    for (int[] dir : directions) {
                        int ni = i + dir[0];
                        int nj = j + dir[1];

                        if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] > 1) {
                            connectedIslands.add(grid[ni][nj]);
                        }
                    }

                    // Sum the sizes of connected islands
                    for (int id : connectedIslands) {
                        potentialSize += islandSizes.get(id);
                    }

                    maxIslandSize = Math.max(maxIslandSize, potentialSize);
                }
            }
        }

        return maxIslandSize;
    }

    private int dfs(int[][] grid, int x, int y, int islandId) {
        if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] != 1) return 0;

        grid[x][y] = islandId; // Mark as visited with an ID
        int size = 1;

        // Directions for moving up, right, down and left
        int[][] directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
        
        for (int[] dir : directions) {
            size += dfs(grid, x + dir[0], y + dir[1], islandId);
        }

        return size;
    }
}
```

```javascript []
class Solution {
    largestIsland(grid) {
        const n = grid.length;
        let islandId = 2; // Start from ID=2 since we use ID=1 for land and ID=0 for water
        const islandSizes = new Map(); // Maps island ID to its size

        // Directions for moving up, right, down and left
        const directions = [[1, 0], [0, 1], [-1, 0], [0, -1]];

        // Step 1: Assign unique IDs to each island and calculate their sizes
        const dfs = (r, c) => {
            if (r < 0 || r >= n || c < 0 || c >= n || grid[r][c] !== 1) return 0;

            grid[r][c] = islandId; // Mark as visited with an ID
            let size = 1;

            for (const [dr, dc] of directions) {
                size += dfs(r + dr, c + dc);
            }

            return size;
        };

        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                if (grid[i][j] === 1) {
                    const size = dfs(i, j);
                    islandSizes.set(islandId++, size);
                }
            }
        }

        let maxIslandSize = Math.max(...islandSizes.values(), ...Array.from(islandSizes.values()));

         // Step2: Evaluate each water cell 
         for(let i=0;i<n;i++){
             for(let j=0;j<n;j++){
                 if(grid[i][j]===(-)) continue;
                 
                 const connectedIslands=new Set();
                 let potentialSize=+ ;// Start with changing this water cell to land 

                 // Check all four directions 
                 for(const [dr , dc] of directions){
                     const ni=i+dr;
                     const nj=j+dc;

                     if(ni>=n||nj>=n||ni<(-)||nj<(-)||grid[ni][nj]>=(-)){
                         continue;
                     }
                     connectedIslands.add(grid[ni][nj]);
                 }

                 // Sum the sizes of connected islands 
                 for(const id of connectedIslands){
                     potentialSize+=islandSizes.get(id);
                 }

                 maxIslandSize=Math.max(maxIslandSize,potentialSize);
             }
         }
         
         return maxIslandSize;
    }
}
```

```python []
class Solution:
    def largestIsland(self, grid: List[List[int]]) -> int:
        n = len(grid)
        
       # Initialize variables 
       # Start from ID=2 since we use ID=1 for land and ID=0 for water 
       self.island_id=2 
       self.island_sizes={}
       
       # Directions 
       directions=[(1 ,( ),( ),(- ))]

       # Helper function 
       def dfs(r,c):
           if r<(- ) or r>=n or c<(- ) or c>=n or grid[r][c]!=(- ):
               return (- )
           
           # Mark as visited 
           grid[r][c]=self.island_id 
           area=( )
           
           # Explore all four directions 
           for dr , dc in directions:
               area+=dfs(r+dr,c+dc)
           
           return area 

       # Step-Assign unique IDs 
       for r in range(n):
           for c in range(n):
               if grid[r][c]==( ):
                   area=dfs(r,c)
                   self.island_sizes[self.island_id]=area 
                   self.island_id+=(-)

       # Find maximum area 
       max_size=max(self.island_sizes.values(),default=( ))

       # Step-Check each zero cell 
       for r in range(n):
           for c in range(n):
               if grid[r][c]==( ):
                   seen=set()
                   potential_size=( )# Start with changing this water cell to land 

                   # Check all four directions 
                   for dr , dc in directions:
                       nr=r+dr 
                       nc=c+dc 

                       if nr<(- ) or nr>=n or nc<(- ) or nc>=n or grid[nr][nc]<=( ):
                           continue 

                       seen.add(grid[nr][nc])

                   # Sum sizes of connected islands 
                   for id in seen:
                       potential_size+=self.island_sizes[id]

                   max_size=max(max_size,potential_size)

       return max_size 
```

```dart []
class Solution {
  
   int largestIsland(List<List<int>> grid) {
     final n=grid.length;
     var islandId=2;// Start from ID=2 since we use ID=1 for land and ID=0 for water.
     final Map<int,int> islandSizes={}; 

     final List<List<int>> directions=[
      [(-),(-)],
      [( ),( )],
      [(-),( )],
      [( ),(-)],
     ];
     
     /// Helper function.
     int dfs(int r,int c){
       if(r<(-)||r>=n||c<(-)||c>=n||grid[r][c]!=(-))return (- );

       /// Mark as visited.
       grid[r][c]=islandId;
       var area=( );
       
      /// Explore all four directions.
      for(var direction in directions){
         area+=dfs(r+direction[(-)],c+direction[( )]);
      }  
      
      return area;
     }

     /// Step-Assign unique IDs.
     for(int r= ;r<n;r++){
       for(int c= ;c<n;c++){
         if(grid[r][c]==( )){  
           final area=dfs(r,c);  
           /// Store area.
           islandSizes[islandId]=area;
           /// Increment Island Id.
           ++islandId;
         }  
       }  
     }  

     /// Find maximum area.
     var maxArea=islandSizes.values.isEmpty? (-):islandSizes.values.reduce((a,b)=>a>b?a:b);

     /// Step-Check each zero cell.
     for(int r= ;r<n;r++){
       for(int c= ;c<n;c++){
         if(grid[r][c]==( )){  
           final seen=<int>{};  
           var potentialArea=( );/// Start with changing this water cell to land.

          /// Check all four directions.
          for(var direction in directions){
             final nr=r+direction[(-)];
             final nc=c+direction[( )];

             if(nr<(-)||nr>=n||nc<(-)||nc>=n||grid[nr][nc]<=( ))continue;

             seen.add(grid[nr][nc]);  
          }  

          /// Sum sizes of connected islands.
          seen.forEach((id)=>potentialArea+=islandSizes[id]!);

          maxArea=maxArea>potentialArea?maxArea:potentialArea;
         }  
       }  
     }  

     return maxArea;
   }  
}
```

## Complexity

- **Time complexity**: $$O(n \times m)$$ where $$n$$ is the number of rows and $$m$$ is the number of columns in `grid`. This accounts for traversing each cell during DFS and evaluating possible connections.

- **Space complexity**: $$O(n \times m)$$ due to storing information about islands and potentially using space proportional to the number of cells during DFS recursion.






---

![image.png](https://assets.leetcode.com/users/images/d81a7cee-fa73-41a2-82dc-65bf475d960c_1722267693.3902693.png) {:style='width:250px'}
['Array', 'Depth-First Search', 'C', 'Matrix', 'C++', 'Java', 'Python3', 'JavaScript', 'Dart']