Skip to content

Latest commit

 

History

History

827

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

You are given an n x n binary matrix grid. You are allowed to change at most one 0 to be 1.

Return the size of the largest island in grid after applying this operation.

An island is a 4-directionally connected group of 1s.

 

Example 1:

Input: grid = [[1,0],[0,1]]
Output: 3
Explanation: Change one 0 to 1 and connect two 1s, then we get an island with area = 3.

Example 2:

Input: grid = [[1,1],[1,0]]
Output: 4
Explanation: Change the 0 to 1 and make the island bigger, only one island with area = 4.

Example 3:

Input: grid = [[1,1],[1,1]]
Output: 4
Explanation: Can't change any 0 to 1, only one island with area = 4.

 

Constraints:

  • n == grid.length
  • n == grid[i].length
  • 1 <= n <= 500
  • grid[i][j] is either 0 or 1.

Companies:
Facebook, Amazon, Apple

Related Topics:
Array, Depth-First Search, Breadth-First Search, Union Find, Matrix

Solution 1. Union Find

// OJ: https://leetcode.com/problems/making-a-large-island/
// Author: github.com/lzl124631x
// Time: O(MN)
// Space: O(MN)
class UnionFind {
    vector<int> id, size;
public:
    UnionFind(int N) : id(N), size(N, 1) {
        iota(begin(id), end(id), 0);
    }
    int find(int x) {
        return id[x] == x ? x : (id[x] = find(id[x]));
    }
    void connect(int x, int y) {
        int p = find(x), q = find(y);
        if (p == q) return;
        id[p] = q;
        size[q] += size[p];
    }
    int getSize(int x) { return size[find(x)]; }
};
class Solution {
public:
    int largestIsland(vector<vector<int>>& G) {
        int M = G.size(), N = G[0].size(), dirs[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}, ans = 0;
        UnionFind uf(M * N);
        for (int i = 0; i < M; ++i) {
            for (int j = 0; j < N; ++j) {
                if (G[i][j] == 0) continue;
                for (auto &[dx, dy] : dirs) {
                    int x = i + dx, y = j + dy;
                    if (x < 0 || y < 0 || x >= M || y >= N || G[x][y] == 0) continue;
                    uf.connect(i * N + j, x * N + y);
                }
                ans = max(ans, uf.getSize(i * N + j));
            }
        }
        for (int i = 0; i < M; ++i) {
            for (int j = 0; j < N; ++j) {
                if (G[i][j] == 1) continue;
                unordered_map<int, int> m;
                for (auto &[dx, dy] : dirs) {
                    int x = i + dx, y = j + dy;
                    if (x < 0 || y < 0 || x >= M || y >= N || G[x][y] == 0) continue;
                    m[uf.find(x * N + y)] = uf.getSize(x * N + y);
                }
                int size = 1;
                for (auto &p : m) size += p.second;
                ans = max(ans, size);
            }
        }
        return ans;
    }
};