给定一个布尔2D矩阵。任务是找到一组独立的岛的数量,其中一组相连的1(水平或垂直)构成一个岛。当且仅当一个岛与另一个岛相等(未旋转或反射)时,才认为两个岛是不同的。
例子:
Input: grid[][] =
{{1, 1, 0, 0, 0},
1, 1, 0, 0, 0},
0, 0, 0, 1, 1},
0, 0, 0, 1, 1}}
Output: 1
Island 1, 1 at the top left corner is same as island 1, 1 at the bottom right corner
Input: grid[][] =
{{1, 1, 0, 1, 1},
1, 0, 0, 0, 0},
0, 0, 0, 0, 1},
1, 1, 0, 1, 1}}
Output: 3
Distinct islands in the example above are: 1, 1 at the top left corner; 1, 1 at the top right corner and 1 at the bottom right corner. We ignore the island 1, 1 at the bottom left corner since 1, 1 it is identical to the top right corner.
方法:此问题是岛屿数量问题的扩展。
问题的核心是知道两个岛是否相等。主要标准是两者中的1数应相同。但这并不是我们在上面的示例2中看到的唯一标准。那么我们怎么知道呢?我们可以使用1的位置/坐标。
如果我们将任何岛屿的第一个坐标作为基点,然后从该基点计算其他点的坐标,则可以消除重复项以得到不同的岛屿数。因此,使用这种方法,可以将上面示例1中2个岛的坐标表示为:[(0,0),(0,1),(1,0),(1,1)]。
下面是上述方法的实现:
C++
// C++ implementation of above approach
#include
using namespace std;
// 2D array for the storing the horizontal and vertical
// directions. (Up, left, down, right}
vector > dirs = { { 0, -1 },
{ -1, 0 },
{ 0, 1 },
{ 1, 0 } };
// Function to perform dfs of the input grid
void dfs(vector >& grid, int x0, int y0,
int i, int j, vector >& v)
{
int rows = grid.size(), cols = grid[0].size();
if (i < 0 || i >= rows || j < 0
|| j >= cols || grid[i][j] <= 0)
return;
// marking the visited element as -1
grid[i][j] *= -1;
// computing coordinates with x0, y0 as base
v.push_back({ i - x0, j - y0 });
// repeat dfs for neighbors
for (auto dir : dirs) {
dfs(grid, x0, y0, i + dir[0], j + dir[1], v);
}
}
// Main function that returns distinct count of islands in
// a given boolean 2D matrix
int countDistinctIslands(vector >& grid)
{
int rows = grid.size();
if (rows == 0)
return 0;
int cols = grid[0].size();
if (cols == 0)
return 0;
set > > coordinates;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
// If a cell is not 1
// no need to dfs
if (grid[i][j] != 1)
continue;
// vector to hold coordinates
// of this island
vector > v;
dfs(grid, i, j, i, j, v);
// insert the coordinates for
// this island to set
coordinates.insert(v);
}
}
return coordinates.size();
}
// Driver code
int main()
{
vector > grid = { { 1, 1, 0, 1, 1 },
{ 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1 },
{ 1, 1, 0, 1, 1 } };
cout << "Number of distinct islands is "
<< countDistinctIslands(grid);
return 0;
}
Python3
# Python implementation of above approach
# 2D array for the storing the horizontal and vertical
# directions. (Up, left, down, right
dirs = [ [ 0, -1 ],
[ -1, 0 ],
[ 0, 1 ],
[ 1, 0 ] ]
# Function to perform dfs of the input grid
def dfs(grid, x0, y0, i, j, v):
rows = len(grid)
cols = len(grid[0])
if i < 0 or i >= rows or j < 0 or j >= cols or grid[i][j] <= 0:
return
# marking the visited element as -1
grid[i][j] *= -1
# computing coordinates with x0, y0 as base
v.append( (i - x0, j - y0) )
# repeat dfs for neighbors
for dir in dirs:
dfs(grid, x0, y0, i + dir[0], j + dir[1], v)
# Main function that returns distinct count of islands in
# a given boolean 2D matrix
def countDistinctIslands(grid):
rows = len(grid)
if rows == 0:
return 0
cols = len(grid[0])
if cols == 0:
return 0
coordinates = set()
for i in range(rows):
for j in range(cols):
# If a cell is not 1
# no need to dfs
if grid[i][j] != 1:
continue
# to hold coordinates
# of this island
v = []
dfs(grid, i, j, i, j, v)
# insert the coordinates for
# this island to set
coordinates.add(tuple(v))
return len(coordinates)
# Driver code
grid = [[ 1, 1, 0, 1, 1 ],
[ 1, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 1 ],
[ 1, 1, 0, 1, 1 ] ]
print("Number of distinct islands is", countDistinctIslands(grid))
# This code is contributed by ankush_953
Number of distinct islands is 3
时间复杂度: O(行*列)
空间复杂度: O(rows * cols)