LeetCode //C - 407. Trapping Rain Water II

407. Trapping Rain Water II

Given an m x n integer matrix heightMap representing the height of each unit cell in a 2D elevation map, return the volume of water it can trap after raining.

Example 1:

Input: heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
Output: 4
Explanation: After the rain, water is trapped between the blocks.

We have two small ponds 1 and 3 units trapped.

The total volume of water trapped is 4.

Example 2:

Input: 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]]
Output: 10

Constraints:
  • m == heightMap.length
  • n == heightMap[i].length
  • 1 <= m, n <= 200
  • 0 < = h e i g h t M a p [ i ] [ j ] < = 2 ∗ 1 0 4 0 <= heightMap[i][j] <= 2 * 10^4 0<=heightMap[i][j]<=2∗104

From: LeetCode

Link: 407. Trapping Rain Water II


Solution:

Ideas:

1. Dynamic Min-Heap Implementation:

  • A MinHeap structure is created to manage the elements in the heap. It includes functions for initializing the heap, inserting elements, and extracting the minimum element.
  • The capacity of the heap is doubled whenever it is full, avoiding the issues of insufficient space.

2. Element Structure:

  • The Element structure is used to store the coordinates and height of each cell.

3. Boundary Processing:

  • The code ensures boundary cells are added to the heap correctly and avoids overwriting memory by properly managing the heap size.

4. Clean-up:

  • Proper memory deallocation is done to avoid memory leaks.
Code:
c 复制代码
typedef struct {
    int x, y;
    int height;
} Element;

typedef struct {
    Element *elements;
    int size;
    int capacity;
} MinHeap;

void initMinHeap(MinHeap *heap, int capacity) {
    heap->elements = (Element *)malloc(sizeof(Element) * capacity);
    heap->size = 0;
    heap->capacity = capacity;
}

void swap(Element *a, Element *b) {
    Element temp = *a;
    *a = *b;
    *b = temp;
}

void insertMinHeap(MinHeap *heap, Element element) {
    if (heap->size == heap->capacity) {
        heap->capacity *= 2;
        heap->elements = (Element *)realloc(heap->elements, sizeof(Element) * heap->capacity);
    }
    heap->elements[heap->size] = element;
    int i = heap->size++;
    while (i > 0) {
        int parent = (i - 1) / 2;
        if (heap->elements[i].height < heap->elements[parent].height) {
            swap(&heap->elements[i], &heap->elements[parent]);
            i = parent;
        } else {
            break;
        }
    }
}

Element extractMin(MinHeap *heap) {
    Element minElement = heap->elements[0];
    heap->elements[0] = heap->elements[--heap->size];
    int i = 0;
    while (true) {
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int smallest = i;
        if (left < heap->size && heap->elements[left].height < heap->elements[smallest].height) {
            smallest = left;
        }
        if (right < heap->size && heap->elements[right].height < heap->elements[smallest].height) {
            smallest = right;
        }
        if (smallest == i) {
            break;
        }
        swap(&heap->elements[i], &heap->elements[smallest]);
        i = smallest;
    }
    return minElement;
}

bool isInBounds(int x, int y, int m, int n) {
    return x >= 0 && x < m && y >= 0 && y < n;
}

int trapRainWater(int** heightMap, int heightMapSize, int* heightMapColSize) {
    if (heightMapSize == 0 || *heightMapColSize == 0) {
        return 0;
    }

    int m = heightMapSize;
    int n = *heightMapColSize;
    int totalWater = 0;

    bool **visited = (bool **)malloc(m * sizeof(bool *));
    for (int i = 0; i < m; i++) {
        visited[i] = (bool *)malloc(n * sizeof(bool));
        for (int j = 0; j < n; j++) {
            visited[i][j] = false;
        }
    }

    MinHeap heap;
    initMinHeap(&heap, m * n);

    // Add all boundary cells to the min-heap
    for (int i = 0; i < m; i++) {
        visited[i][0] = true;
        visited[i][n - 1] = true;
        insertMinHeap(&heap, (Element){i, 0, heightMap[i][0]});
        insertMinHeap(&heap, (Element){i, n - 1, heightMap[i][n - 1]});
    }
    for (int j = 0; j < n; j++) {
        visited[0][j] = true;
        visited[m - 1][j] = true;
        insertMinHeap(&heap, (Element){0, j, heightMap[0][j]});
        insertMinHeap(&heap, (Element){m - 1, j, heightMap[m - 1][j]});
    }

    int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    
    // Process the heap
    while (heap.size > 0) {
        Element current = extractMin(&heap);
        int x = current.x;
        int y = current.y;
        int currentHeight = current.height;

        for (int j = 0; j < 4; j++) {
            int nx = x + directions[j][0];
            int ny = y + directions[j][1];
            
            if (isInBounds(nx, ny, m, n) && !visited[nx][ny]) {
                visited[nx][ny] = true;
                // Calculate the water that can be trapped
                if (currentHeight > heightMap[nx][ny]) {
                    totalWater += currentHeight - heightMap[nx][ny];
                }
                // Add the neighbor to the heap with the maximum height
                insertMinHeap(&heap, (Element){nx, ny, heightMap[nx][ny] > currentHeight ? heightMap[nx][ny] : currentHeight});
            }
        }
    }

    // Clean up
    for (int i = 0; i < m; i++) {
        free(visited[i]);
    }
    free(visited);
    free(heap.elements);

    return totalWater;
}
相关推荐
闻缺陷则喜何志丹4 分钟前
【二分查找、滑动窗口】P10389 [蓝桥杯 2024 省 A] 成绩统计|普及+
c++·算法·蓝桥杯·二分查找·滑动窗口·洛谷·成绩
威哥爱编程1 小时前
C语言操作MySQL从入门到精通
c语言·数据库·mysql
乔冠宇1 小时前
蓝桥杯算法——铠甲合体
算法·职场和发展·蓝桥杯
商bol451 小时前
算阶,jdk和idea的安装
数据结构·c++·算法
迷迭所归处1 小时前
C语言 —— 愿文明如薪火般灿烂 - 函数递归
c语言·开发语言·算法
yyytucj1 小时前
C/C++通过SQLiteSDK增删改查
c语言·jvm·c++
冱洇3 小时前
168. Excel 表列名称
leetcode
柠檬鲨_4 小时前
C语言100天练习题【记录本】
c语言·数据结构·算法
float_六七4 小时前
二叉树三种遍历方式——前序、中序、后序(C++)
开发语言·c++·算法
CYRUS_STUDIO9 小时前
常用加解密算法介绍
算法·安全·逆向