407. 接雨水 II

1. 题号和题目名称

  1. 接雨水 II

2. 题目叙述

给你一个 m x n 的矩阵表示一个地图的高度图,其中 heightMap[i][j] 表示坐标 (i, j) 处的高度。

请你计算这个地图能接多少体积的雨水。

示例 1

输入: heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
输出: 4
解释: 下雨后,雨水将会被存储在这些方块中。总的接雨水量是 4。

示例 2

输入: heightMap = [[3,3,3,3,3],[3,2,2,2,3],[3,2,1,2,3],[3,2,2,2,3],[3,3,3,3,3]]
输出: 10

3. 模式识别

本题可使用优先队列(最小堆)来解决。核心思路是从地图的边界开始,因为边界上的方块无法积水,将边界上的方块加入优先队列,然后不断从优先队列中取出高度最小的方块,向其相邻的方块扩展,根据相邻方块与当前方块的高度关系来计算积水量。

4. 考点分析

  • 优先队列(最小堆):使用优先队列来维护当前可扩展的方块中高度最小的方块。
  • 广度优先搜索(BFS):从边界开始向内部扩展,不断更新方块的状态。
  • 二维数组操作:对二维矩阵进行遍历和操作。

5. 所有解法

  • 优先队列 + BFS 解法:上述提到的核心解法,时间复杂度和空间复杂度相对较优。
  • 暴力解法:对于每个方块,计算其四周的最小高度,然后根据该高度和当前方块高度的差值计算积水量,但这种方法时间复杂度较高。

6. 最优解法(优先队列 + BFS)的 C 语言代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义优先队列的节点结构体
typedef struct {
   
    int x, y;  // 方块在二维矩阵(高度图)中的坐标,x 表示行,y 表示列
    int height;  // 该方块的高度
} Node;

// 定义优先队列结构体
typedef struct {
   
    Node *data;  // 用于存储节点的数组,动态分配内存
    int size;    // 当前优先队列中节点的数量
    int capacity;  // 优先队列的容量,即最多能存储的节点数
} PriorityQueue;

// 交换两个节点
void swap(Node *a, Node *b) {
   
    Node temp = *a;  // 临时变量存储节点 a 的值
    *a = *b;  // 将节点 b 的值赋给节点 a
    *b = temp;  // 将临时变量的值赋给节点 b,完成交换
}

// 调整堆,使其满足最小堆的性质
// pq: 指向优先队列的指针
// idx: 当前要调整的节点的索引
void heapify(PriorityQueue *pq, int idx) {
   
    int left = 2 * idx + 1;  // 计算当前节点的左子节点索引
    int right = 2 * idx + 2;  // 计算当前节点的右子节点索引
    int smallest = idx;  // 假设当前节点是最小的

    // 如果左子节点存在且其高度小于当前最小节点的高度
    if (left < pq->size && pq->data[left].height < pq->data[smallest].height) {
   
        smallest = left;  // 更新最小节点为左子节点
    }
    // 如果右子节点存在且其高度小于当前最小节点的高度
    if (right < pq->size && pq->data[right
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

请向我看齐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值