华为OD机试 - 最大岛屿体积 - 深度优先搜索dfs(Python/JS/C/C++ 2025 B卷 200分)

在这里插入图片描述

2025B卷华为OD机试统一考试题库清单(持续收录中)以及考点说明(Python/JS/C/C++)

专栏导读

本专栏收录于《华为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

五、解题思路

  1. 使用二维数组来表示地图
  2. 使用布尔型二维数组来记录已访问的单元格
  3. 采用深度优先搜索(DFS)来查找所有连通的岛屿
  4. 对每一个未访问的陆地单元格,启动一次DFS遍历
  5. 在DFS过程中,累加所有连通陆地单元格的值,计算岛屿体积
  6. 记录找到的最大岛屿体积

为什么选择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算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值