https://leetcode.com/problems/making-a-large-island/description/
給定 gird
,最多可以將裡面一個 0
翻轉成 1
1
所連成的區域為島嶼 ,這個連法只能上下左右,無法斜著對角連線
回傳經過操作後,grid
最大的島嶼面積?
Constraints:
想當然,我們可以用 DFS or BFS 來遍歷這張圖
因為元素只會是 0
or 1
,所以我們可以用比 1
大的值作為標記來劃分圖上不同的島嶼
接著,我們就把每個 0
都試著變成 1
看看跟它周圍的島嶼連接後的大小如何
class Solution
{
public:
int largestIsland(vector<vector<int>> &grid)
{
const int n = grid.size();
vector<int> islandSize;
islandSize.reserve(n * n);
int label = 2, ans = 0;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (grid[i][j] == 1)
{
islandSize.push_back(dfs(grid, i, j, label++));
ans = max(ans, islandSize.back());
}
}
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (grid[i][j] == 0)
ans = max(ans, connectIslands(grid, islandSize, i, j));
}
}
return ans;
}
private:
static constexpr array<array<int, 2>, 4> directions = {{
{0, 1},
{1, 0},
{0, -1},
{-1, 0},
}};
bool isBounded(int ordX, int ordY, int n) noexcept
{
return ordX >= 0 && ordY >= 0 && ordX < n && ordY < n;
}
int dfs(vector<vector<int>> &grid, int x, int y, int label)
{
const int n = grid.size();
grid[x][y] = label;
int size = 1;
for (const auto direction : directions)
{
const int ordX = x + direction[0];
const int ordY = y + direction[1];
if (isBounded(ordX, ordY, n) && grid[ordX][ordY] == 1)
size += dfs(grid, ordX, ordY, label);
}
return size;
}
int connectIslands(vector<vector<int>> &grid, vector<int> &islandSize, int x, int y)
{
const int n = grid.size();
int visited[4] = {0};
int newSize = 1, directIdx = 0;
for (const auto direction : directions)
{
const int ordX = x + direction[0];
const int ordY = y + direction[1];
if (!isBounded(ordX, ordY, n))
continue;
const int label = grid[ordX][ordY];
if (label > 1)
{
bool found = false;
for (int i = 0; i < directIdx; ++i)
{
if (visited[i] == label)
{
found = true;
break;
}
}
if (!found)
{
visited[directIdx++] = label;
newSize += islandSize[label - 2];
}
}
}
return newSize;
}
};
func largestIsland(grid [][]int) int {
n := len(grid)
islandSize := make([]int, n*n)
label, ans := 2, 0
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 1 {
size := dfs(grid, i, j, label)
islandSize[label-2] = size
ans = max(ans, size)
label++
}
}
}
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 0 {
ans = max(ans, connectIslands(grid, islandSize, i, j))
}
}
}
return ans
}
var directions = [4][2]int{
{0, 1}, {1, 0}, {0, -1}, {-1, 0},
}
func isBounded(x, y, n int) bool {
return x >= 0 && y >= 0 && x < n && y < n
}
func dfs(grid [][]int, x, y, label int) int {
n := len(grid)
grid[x][y] = label
size := 1
for _, direction := range directions {
ordX, ordY := x+direction[0], y+direction[1]
if isBounded(ordX, ordY, n) && grid[ordX][ordY] == 1 {
size += dfs(grid, ordX, ordY, label)
}
}
return size
}
func connectIslands(grid [][]int, islandSize []int, x, y int) int {
n := len(grid)
visited := [4]int{0, 0, 0, 0}
newSize, idx := 1, 0
for _, direction := range directions {
ordX, ordY := x+direction[0], y+direction[1]
if isBounded(ordX, ordY, n) {
label := grid[ordX][ordY]
if label > 1 {
found := false
for i := 0; i < idx; i++ {
if visited[i] == label {
found = true
break
}
}
if !found {
visited[idx] = label
idx++
newSize += islandSize[label-2]
}
}
}
}
return newSize
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up