2023-05-07:给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。 返回执行此操作后,grid 中最大的岛屿面积是多少? 岛屿 由一组上、下、左、右四个方向相

2023-05-07:给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。

返回执行此操作后,grid 中最大的岛屿面积是多少?

岛屿 由一组上、下、左、右四个方向相连的 1 形成。

输入: grid = [[1, 0], [0, 1]]。

输出: 3。

来自亚马逊、谷歌、微软、Facebook、Bloomberg。

答案2023-05-07:

算法步骤:

1.遍历输入矩阵 grid,对于每个岛屿进行标记,并用数组 sizes 统计每个岛屿的大小。

2.遍历矩阵 grid,对于每个位置上的值,如果当前位置上的值为非零正整数,则更新答案为当前岛屿的大小。

3.遍历矩阵 grid,当当前位置上的值为 0 时,分别查看该位置上、下、左、右四个方向是否有与其相邻且已经被访问过的岛屿,并将它们的大小累加起来。如果这些岛屿的大小之和加上当前位置上自身的大小可以更新最大岛屿面积,则更新答案。

4.返回答案。

时间复杂度:O(n^2) ,遍历了三次矩阵,每次遍历的时间复杂度均为 O(n^2)

空间复杂度:O(n^2),使用了两个二维数组,每个数组都是 n \times n 的大小。

go完整代码如下:

package main

import "fmt"

func main() {
    grid := [][]int{{1, 0}, {0, 1}}
    ans := largestIsland(grid)
    fmt.Println(ans)
}

func largestIsland(grid [][]int) int {
    n := len(grid)
    m := len(grid[0])
    id := 2
    for i := 0; i < n; i++ {
        for j := 0; j < m; j++ {
            if grid[i][j] == 1 {
                infect(grid, i, j, id, n, m)
                id++
            }
        }
    }
    sizes := make([]int, id)
    ans := 0
    for i := 0; i < n; i++ {
        for j := 0; j < m; j++ {
            if grid[i][j] > 1 {
                sizes[grid[i][j]]++
                ans = max(ans, sizes[grid[i][j]])
            }
        }
    }
    visited := make([]bool, id)
    for i := 0; i < n; i++ {
        for j := 0; j < m; j++ {
            if grid[i][j] == 0 {
                up := 0
                if i-1 >= 0 {
                    up = grid[i-1][j]
                }
                down := 0
                if i+1 < n {
                    down = grid[i+1][j]
                }
                left := 0
                if j-1 >= 0 {
                    left = grid[i][j-1]
                }
                right := 0
                if j+1 < m {
                    right = grid[i][j+1]
                }
                merge := 1 + sizes[up]
                visited[up] = true
                if !visited[down] {
                    merge += sizes[down]
                    visited[down] = true
                }
                if !visited[left] {
                    merge += sizes[left]
                    visited[left] = true
                }
                if !visited[right] {
                    merge += sizes[right]
                    visited[right] = true
                }
                ans = max(ans, merge)
                visited[up] = false
                visited[down] = false
                visited[left] = false
                visited[right] = false
            }
        }
    }
    return ans
}

func infect(grid [][]int, i, j, v, n, m int) {
    if i < 0 || i == n || j < 0 || j == m || grid[i][j] != 1 {
        return
    }
    grid[i][j] = v
    infect(grid, i-1, j, v, n, m)
    infect(grid, i+1, j, v, n, m)
    infect(grid, i, j-1, v, n, m)
    infect(grid, i, j+1, v, n, m)
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

[图片上传失败...(image-b481ac-1683460340723)]

rust完整代码如下:

fn main() {
    let grid = vec![vec![1, 0], vec![0, 1]];
    let ans = largest_island(grid);
    println!("{}", ans);
}

fn largest_island(grid: Vec<Vec<i32>>) -> i32 {
    let n = grid.len();
    let m = grid[0].len();
    let mut id = 2;
    let mut new_grid = grid.clone();
    for i in 0..n {
        for j in 0..m {
            if new_grid[i][j] == 1 {
                infect(&mut new_grid, i as i32, j as i32, id, n as i32, m as i32);
                id += 1;
            }
        }
    }
    let mut sizes = vec![0; id as usize];
    let mut ans = 0;
    for i in 0..n {
        for j in 0..m {
            if new_grid[i][j] > 1 {
                sizes[new_grid[i][j] as usize] += 1;
                ans = ans.max(sizes[new_grid[i][j] as usize]);
            }
        }
    }
    let mut visited = vec![false; id as usize];
    for i in 0..n {
        for j in 0..m {
            if new_grid[i][j] == 0 {
                let up = if i > 0 { new_grid[i - 1][j] } else { 0 };
                let down = if i < n - 1 { new_grid[i + 1][j] } else { 0 };
                let left = if j > 0 { new_grid[i][j - 1] } else { 0 };
                let right = if j < m - 1 { new_grid[i][j + 1] } else { 0 };
                let mut merge = 1;
                if up > 0 && !visited[up as usize] {
                    visited[up as usize] = true;
                    merge += sizes[up as usize];
                }
                if down > 0 && !visited[down as usize] {
                    visited[down as usize] = true;
                    merge += sizes[down as usize];
                }
                if left > 0 && !visited[left as usize] {
                    visited[left as usize] = true;
                    merge += sizes[left as usize];
                }
                if right > 0 && !visited[right as usize] {
                    visited[right as usize] = true;
                    merge += sizes[right as usize];
                }
                ans = ans.max(merge);
                visited[up as usize] = false;
                visited[down as usize] = false;
                visited[left as usize] = false;
                visited[right as usize] = false;
            }
        }
    }
    ans
}

fn infect(grid: &mut Vec<Vec<i32>>, i: i32, j: i32, v: i32, n: i32, m: i32) {
    if i < 0 || i == n || j < 0 || j == m || grid[i as usize][j as usize] != 1 {
        return;
    }
    grid[i as usize][j as usize] = v;
    infect(grid, i - 1, j, v, n, m);
    infect(grid, i + 1, j, v, n, m);
    infect(grid, i, j - 1, v, n, m);
    infect(grid, i, j + 1, v, n, m);
}

[图片上传失败...(image-393b93-1683460340723)]

c完整代码如下:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define MAX_SIZE 50

void infect(int grid[][MAX_SIZE], int i, int j, int v, int n, int m);
int largestIsland(int grid[][MAX_SIZE], int n, int m);

int main() {
    int grid[][MAX_SIZE] = { {1, 0}, {0, 1} };
    int n = 2;
    int m = 2;
    int ans = largestIsland(grid, n, m);
    printf("%d\n", ans); // 输出 3
    return 0;
}

int largestIsland(int grid[][MAX_SIZE], int n, int m) {
    int id = 2;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 1) {
                infect(grid, i, j, id++, n, m);
            }
        }
    }
    int sizes[MAX_SIZE * MAX_SIZE];
    memset(sizes, 0, sizeof(sizes));
    int ans = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] > 1) {
                ans = ans > ++sizes[grid[i][j]] ? ans : sizes[grid[i][j]];
            }
        }
    }
    bool visited[MAX_SIZE * MAX_SIZE] = { false };
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 0) {
                int up = i - 1 >= 0 ? grid[i - 1][j] : 0;
                int down = i + 1 < n ? grid[i + 1][j] : 0;
                int left = j - 1 >= 0 ? grid[i][j - 1] : 0;
                int right = j + 1 < m ? grid[i][j + 1] : 0;
                int merge = 1 + sizes[up];
                visited[up] = true;
                if (!visited[down]) {
                    merge += sizes[down];
                    visited[down] = true;
                }
                if (!visited[left]) {
                    merge += sizes[left];
                    visited[left] = true;
                }
                if (!visited[right]) {
                    merge += sizes[right];
                    visited[right] = true;
                }
                ans = ans > merge ? ans : merge;
                visited[up] = false;
                visited[down] = false;
                visited[left] = false;
                visited[right] = false;
            }
        }
    }
    return ans;
}

void infect(int grid[][MAX_SIZE], int i, int j, int v, int n, int m) {
    if (i < 0 || i == n || j < 0 || j == m || grid[i][j] != 1) {
        return;
    }
    grid[i][j] = v;
    infect(grid, i - 1, j, v, n, m);
    infect(grid, i + 1, j, v, n, m);
    infect(grid, i, j - 1, v, n, m);
    infect(grid, i, j + 1, v, n, m);
}

[图片上传失败...(image-89a7ad-1683460340723)]

c++完整代码如下:

#include <iostream>
#include <cstring>
#define MAX_SIZE 50

using namespace std;

void infect(int grid[][MAX_SIZE], int i, int j, int v, int n, int m);
int largestIsland(int grid[][MAX_SIZE], int n, int m);

int main() {
    int grid[][MAX_SIZE] = { {1, 0}, {0, 1} };
    int n = 2;
    int m = 2;
    int ans = largestIsland(grid, n, m);
    cout << ans << endl;
    return 0;
}

int largestIsland(int grid[][MAX_SIZE], int n, int m) {
    int id = 2;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 1) {
                infect(grid, i, j, id++, n, m);
            }
        }
    }
    int sizes[MAX_SIZE * MAX_SIZE];
    memset(sizes, 0, sizeof(sizes)); // 初始化为0
    int ans = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] > 1) {
                ans = max(ans, ++sizes[grid[i][j]]);
            }
        }
    }
    bool visited[MAX_SIZE * MAX_SIZE] = { false }; // 初始化为false
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 0) {
                int up = i - 1 >= 0 ? grid[i - 1][j] : 0;
                int down = i + 1 < n ? grid[i + 1][j] : 0;
                int left = j - 1 >= 0 ? grid[i][j - 1] : 0;
                int right = j + 1 < m ? grid[i][j + 1] : 0;
                int merge = 1 + sizes[up];
                visited[up] = true;
                if (!visited[down]) {
                    merge += sizes[down];
                    visited[down] = true;
                }
                if (!visited[left]) {
                    merge += sizes[left];
                    visited[left] = true;
                }
                if (!visited[right]) {
                    merge += sizes[right];
                    visited[right] = true;
                }
                ans = max(ans, merge);
                visited[up] = false;
                visited[down] = false;
                visited[left] = false;
                visited[right] = false;
            }
        }
    }
    return ans;
}

void infect(int grid[][MAX_SIZE], int i, int j, int v, int n, int m) {
    if (i < 0 || i == n || j < 0 || j == m || grid[i][j] != 1) {
        return;
    }
    grid[i][j] = v;
    infect(grid, i - 1, j, v, n, m);
    infect(grid, i + 1, j, v, n, m);
    infect(grid, i, j - 1, v, n, m);
    infect(grid, i, j + 1, v, n, m);
}

[图片上传失败...(image-3199dc-1683460340723)]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容