专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
给你一个由 大于0的数(陆地)和 0(水)组成的的二维网格,请你计算网格中最大岛屿的体积。陆地的数表示所在岛屿的体积。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
二、输入描述
第一行是二维网格的宽和高。
后面几行是二维网格。
三、输出描述
输出岛屿的最大体积。
四、测试用例
测试用例1
1、输入
3 3
0 0 0
0 0 0
0 0 0
2、输出
0
测试用例2
1、输入
5 3
1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
2、输出
3
五、解题思路
- 使用二维数组来表示地图
- 使用布尔型二维数组来记录已访问的单元格
- 采用深度优先搜索(DFS)来查找所有连通的岛屿
- 对每一个未访问的陆地单元格,启动一次DFS遍历
- 在DFS过程中,累加所有连通陆地单元格的值,计算岛屿体积
- 记录找到的最大岛屿体积
为什么选择DFS:
DFS能有效识别连通区域,时间复杂度为O(nm),其中n和m是网格的维度。每个单元格最多被访问一次,空间复杂度为O(nm),用于存储访问记录和递归栈。
六、Python算法源码
def find_max_island_volume(grid, height, width):
"""
查找最大岛屿体积
:param grid: 二维网格
:param height: 网格高度
:param width: 网格宽度
:return: 最大岛屿体积
"""
visited = [[False for _ in range(width)] for _ in range(height)] # 记录已访问的单元格
max_volume = 0 # 最大体积初始化为0
def dfs(i, j):
"""
使用深度优先搜索计算岛屿体积
:param i: 当前行索引
:param j: 当前列索引
:return: 从当前单元格开始的岛屿体积
"""
# 检查是否越界、是否为水域、是否已访问
if i < 0 or i >= height or j < 0 or j >= width or grid[i][j] == 0 or visited[i][j]:
return 0
# 标记为已访问
visited[i][j] = True
# 计算体积:当前单元格值 + 相邻单元格的体积
volume = grid[i][j]
# 检查四个方向
volume += dfs(i + 1, j) # 下
volume += dfs(i - 1, j) # 上
volume += dfs(i, j + 1) # 右
volume += dfs(i, j - 1) # 左
return volume
# 遍历整个网格
for i in range(height):
for j in range(width):
# 如果是未访问的陆地,则开始深度优先搜索
if grid[i][j] > 0 and not visited[i][j]:
volume = dfs(i, j)
max_volume = max(max_volume, volume) # 更新最大体积
return max_volume
# 读取输入
dimensions = input().split()
width = int(dimensions[0])
height = int(dimensions[1])
grid = []
for _ in range(height):
row = list(map(int, input().split()))
grid.append(row)
# 计算并输出结果
result = find_max_island_volume(grid, height, width)
print(result)
七、JavaScript算法源码
// 获取标准输入
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let lines = [];
rl.on('line', (line) => {
lines.push(line);
});
rl.on('close', () => {
// 读取网格维度
const dimensions = lines[0].split(' ').map(Number);
const width = dimensions[0];
const height = dimensions[1];
// 读取网格数据
const grid = [];
for (let i = 0; i < height; i++) {
grid.push(lines[i + 1].split(' ').map(Number));
}
// 计算并输出结果
const result = findMaxIslandVolume(grid, height, width);
console.log(result);
});
/**
* 查找最大岛屿体积
* @param {number[][]} grid - 二维网格
* @param {number} height - 网格高度
* @param {number} width - 网格宽度
* @return {number} - 最大岛屿体积
*/
function findMaxIslandVolume(grid, height, width) {
// 创建访问记录数组
const visited = Array(height).fill().map(() => Array(width).fill(false));
let maxVolume = 0; // 最大体积初始化为0
/**
* 使用深度优先搜索计算岛屿体积
* @param {number} i - 当前行索引
* @param {number} j - 当前列索引
* @return {number} - 从当前单元格开始的岛屿体积
*/
function dfs(i, j) {
// 检查是否越界、是否为水域、是否已访问
if (i < 0 || i >= height || j < 0 || j >= width || grid[i][j] === 0 || visited[i][j]) {
return 0;
}
// 标记为已访问
visited[i][j] = true;
// 计算体积:当前单元格值 + 相邻单元格的体积
let volume = grid[i][j];
// 检查四个方向
volume += dfs(i + 1, j); // 下
volume += dfs(i - 1, j); // 上
volume += dfs(i, j + 1); // 右
volume += dfs(i, j - 1); // 左
return volume;
}
// 遍历整个网格
for (let i = 0; i < height; i++) {
for (let j = 0; j < width; j++) {
// 如果是未访问的陆地,则开始深度优先搜索
if (grid[i][j] > 0 && !visited[i][j]) {
const volume = dfs(i, j);
maxVolume = Math.max(maxVolume, volume); // 更新最大体积
}
}
}
return maxVolume;
}
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/**
* 使用深度优先搜索计算岛屿体积
* @param grid 二维网格
* @param visited 访问记录
* @param i 当前行索引
* @param j 当前列索引
* @param height 网格高度
* @param width 网格宽度
* @return 从当前单元格开始的岛屿体积
*/
int dfs(int** grid, bool** visited, int i, int j, int height, int width) {
// 检查是否越界、是否为水域、是否已访问
if (i < 0 || i >= height || j < 0 || j >= width || grid[i][j] == 0 || visited[i][j]) {
return 0;
}
// 标记为已访问
visited[i][j] = true;
// 计算体积:当前单元格值 + 相邻单元格的体积
int volume = grid[i][j];
// 检查四个方向
volume += dfs(grid, visited, i + 1, j, height, width); // 下
volume += dfs(grid, visited, i - 1, j, height, width); // 上
volume += dfs(grid, visited, i, j + 1, height, width); // 右
volume += dfs(grid, visited, i, j - 1, height, width); // 左
return volume;
}
/**
* 查找最大岛屿体积
* @param grid 二维网格
* @param height 网格高度
* @param width 网格宽度
* @return 最大岛屿体积
*/
int findMaxIslandVolume(int** grid, int height, int width) {
// 创建访问记录数组
bool** visited = (bool**)malloc(height * sizeof(bool*));
for (int i = 0; i < height; i++) {
visited[i] = (bool*)calloc(width, sizeof(bool)); // 使用calloc初始化为false
}
int maxVolume = 0; // 最大体积初始化为0
// 遍历整个网格
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// 如果是未访问的陆地,则开始深度优先搜索
if (grid[i][j] > 0 && !visited[i][j]) {
int volume = dfs(grid, visited, i, j, height, width);
if (volume > maxVolume) {
maxVolume = volume; // 更新最大体积
}
}
}
}
// 释放访问记录数组内存
for (int i = 0; i < height; i++) {
free(visited[i]);
}
free(visited);
return maxVolume;
}
int main() {
int width, height;
scanf("%d %d", &width, &height);
// 创建网格数组
int** grid = (int**)malloc(height * sizeof(int*));
for (int i = 0; i < height; i++) {
grid[i] = (int*)malloc(width * sizeof(int));
for (int j = 0; j < width; j++) {
scanf("%d", &grid[i][j]);
}
}
// 计算并输出结果
int result = findMaxIslandVolume(grid, height, width);
printf("%d\n", result);
// 释放网格数组内存
for (int i = 0; i < height; i++) {
free(grid[i]);
}
free(grid);
return 0;
}
九、C++算法源码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/**
* 使用深度优先搜索计算岛屿体积
* @param grid 二维网格
* @param visited 访问记录
* @param i 当前行索引
* @param j 当前列索引
* @param height 网格高度
* @param width 网格宽度
* @return 从当前单元格开始的岛屿体积
*/
int dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int i, int j, int height, int width) {
// 检查是否越界、是否为水域、是否已访问
if (i < 0 || i >= height || j < 0 || j >= width || grid[i][j] == 0 || visited[i][j]) {
return 0;
}
// 标记为已访问
visited[i][j] = true;
// 计算体积:当前单元格值 + 相邻单元格的体积
int volume = grid[i][j];
// 检查四个方向
volume += dfs(grid, visited, i + 1, j, height, width); // 下
volume += dfs(grid, visited, i - 1, j, height, width); // 上
volume += dfs(grid, visited, i, j + 1, height, width); // 右
volume += dfs(grid, visited, i, j - 1, height, width); // 左
return volume;
}
/**
* 查找最大岛屿体积
* @param grid 二维网格
* @param height 网格高度
* @param width 网格宽度
* @return 最大岛屿体积
*/
int findMaxIslandVolume(vector<vector<int>>& grid, int height, int width) {
vector<vector<bool>> visited(height, vector<bool>(width, false)); // 记录已访问的单元格
int maxVolume = 0; // 最大体积初始化为0
// 遍历整个网格
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// 如果是未访问的陆地,则开始深度优先搜索
if (grid[i][j] > 0 && !visited[i][j]) {
int volume = dfs(grid, visited, i, j, height, width);
maxVolume = max(maxVolume, volume); // 更新最大体积
}
}
}
return maxVolume;
}
int main() {
int width, height;
cin >> width >> height;
// 创建并读取网格数据
vector<vector<int>> grid(height, vector<int>(width));
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
cin >> grid[i][j];
}
}
// 计算并输出结果
int result = findMaxIslandVolume(grid, height, width);
cout << result << endl;
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 B卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。