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;
}
相关推荐
软工菜鸡25 分钟前
预训练语言模型BERT——PaddleNLP中的预训练模型
大数据·人工智能·深度学习·算法·语言模型·自然语言处理·bert
南宫生28 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
希言JY37 分钟前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若39 分钟前
C语言比较两个字符串是否相同
c语言
AI视觉网奇1 小时前
sklearn 安装使用笔记
人工智能·算法·sklearn
JingHongB1 小时前
代码随想录算法训练营Day55 | 图论理论基础、深度优先搜索理论基础、卡玛网 98.所有可达路径、797. 所有可能的路径、广度优先搜索理论基础
算法·深度优先·图论
weixin_432702261 小时前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
小冉在学习1 小时前
day52 图论章节刷题Part04(110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长 )
算法·深度优先·图论
Repeat7151 小时前
图论基础--孤岛系列
算法·深度优先·广度优先·图论基础
小冉在学习1 小时前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论