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;
}
相关推荐
XH华37 分钟前
初识C语言之二维数组(下)
c语言·算法
南宫生1 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_1 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
落魄君子1 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
菜鸡中的奋斗鸡→挣扎鸡1 小时前
滑动窗口 + 算法复习
数据结构·算法
Lenyiin2 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
郭wes代码2 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
scan7242 小时前
LILAC采样算法
人工智能·算法·机器学习
菌菌的快乐生活2 小时前
理解支持向量机
算法·机器学习·支持向量机
大山同学2 小时前
第三章线性判别函数(二)
线性代数·算法·机器学习