Skip to content

Files

279 lines (241 loc) · 6.96 KB

File metadata and controls

279 lines (241 loc) · 6.96 KB

中文文档

Description

Given a 2D grid consists of 0s (land) and 1s (water).  An island is a maximal 4-directionally connected group of 0s and a closed island is an island totally (all left, top, right, bottom) surrounded by 1s.

Return the number of closed islands.

 

Example 1:

Input: grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]
Output: 2
Explanation: 
Islands in gray are closed because they are completely surrounded by water (group of 1s).

Example 2:

Input: grid = [[0,0,1,0,0],[0,1,0,1,0],[0,1,1,1,0]]
Output: 1

Example 3:

Input: grid = [[1,1,1,1,1,1,1],
               [1,0,0,0,0,0,1],
               [1,0,1,1,1,0,1],
               [1,0,1,0,1,0,1],
               [1,0,1,1,1,0,1],
               [1,0,0,0,0,0,1],
               [1,1,1,1,1,1,1]]
Output: 2

 

Constraints:

  • 1 <= grid.length, grid[0].length <= 100
  • 0 <= grid[i][j] <=1

Solutions

Union find.

Python3

class Solution:
    def closedIsland(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        p = list(range(m * n))

        def find(x):
            if p[x] != x:
                p[x] = find(p[x])
            return p[x]

        for i in range(m):
            for j in range(n):
                if grid[i][j] == 1:
                    continue
                idx = i * n + j
                if i < m - 1 and grid[i + 1][j] == 0:
                    p[find(idx)] = find((i + 1) * n + j)
                if j < n - 1 and grid[i][j + 1] == 0:
                    p[find(idx)] = find(i * n + j + 1)

        s = [0] * (m * n)
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 0:
                    s[find(i * n + j)] = 1
        for i in range(m):
            for j in range(n):
                root = find(i * n + j)
                if not s[root]:
                    continue
                if i == 0 or i == m - 1 or j == 0 or j == n - 1:
                    s[root] = 0
        return sum(s)

Java

class Solution {
    private int[] p;

    public int closedIsland(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        p = new int[m * n];
        for (int i = 0; i < m * n; ++i) {
            p[i] = i;
        }
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    continue;
                }
                int idx = i * n + j;
                if (i < m - 1 && grid[i + 1][j] == 0) {
                    p[find(idx)] = find((i + 1) * n + j);
                }
                if (j < n - 1 && grid[i][j + 1] == 0) {
                    p[find(idx)] = find(i * n + j + 1);
                }
            }
        }
        boolean[] s = new boolean[m * n];
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 0) {
                    s[find(i * n + j)] = true;
                }
            }
        }
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                int root = find(i * n + j);
                if (!s[root]) {
                    continue;
                }
                if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
                    s[root] = false;
                }
            }
        }
        int res = 0;
        for (int i = 0; i < m * n; ++i) {
            if (s[i]) {
                ++res;
            }
        }
        return res;
    }

    private int find(int x) {
        if (p[x] != x) {
            p[x] = find(p[x]);
        }
        return p[x];
    }
}

C++

class Solution {
public:
    vector<int> p;

    int closedIsland(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        p.resize(m * n);
        for (int i = 0; i < m * n; ++i) p[i] = i;
        for (int i = 0; i < m; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                if (grid[i][j] == 1) continue;
                int idx = i * n + j;
                if (i < m - 1 && grid[i + 1][j] == 0) p[find(idx)] = find((i + 1) * n + j);
                if (j < n - 1 && grid[i][j + 1] == 0) p[find(idx)] = find(i * n + j + 1);
            }
        }
        vector<bool> s(m * n, false);
        for (int i = 0; i < m; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                if (grid[i][j] == 0) s[find(i * n + j)] = true;
            }
        }
        for (int i = 0; i < m; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                int root = find(i * n + j);
                if (!s[root]) continue;
                if (i == 0 || i == m - 1 || j == 0 || j == n - 1) s[root] = false;
            }
        }
        int res = 0;
        for (auto e : s)
        {
            if (e) ++res;
        }
        return res;
    }

    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
};

Go

var p []int

func closedIsland(grid [][]int) int {
	m, n := len(grid), len(grid[0])
	p = make([]int, m*n)
	for i := 0; i < len(p); i++ {
		p[i] = i
	}
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			if grid[i][j] == 1 {
				continue
			}
			idx := i*n + j
			if i < m-1 && grid[i+1][j] == 0 {
				p[find(idx)] = find((i+1)*n + j)
			}
			if j < n-1 && grid[i][j+1] == 0 {
				p[find(idx)] = find(i*n + j + 1)
			}
		}
	}
	s := make([]bool, m*n)
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			if grid[i][j] == 0 {
				s[find(i*n+j)] = true
			}
		}
	}
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			root := find(i*n + j)
			if !s[root] {
				continue
			}
			if i == 0 || i == m-1 || j == 0 || j == n-1 {
				s[root] = false
			}
		}
	}
	res := 0
	for _, e := range s {
		if e {
			res++
		}
	}
	return res
}

func find(x int) int {
	if p[x] != x {
		p[x] = find(p[x])
	}
	return p[x]
}

...