接雨水

55 阅读1分钟

问题总览

序号题目完成
坐标轴11. 盛最多水的容器
直方图(一维数组)42. 接雨水
矩阵(二维数组)407. 接雨水 II

11. 盛最多水的容器

class Solution {
    public int maxArea(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int max = 0;
        while (left < right) {
            max = Math.max(max, (right - left) * Math.min(height[left], height[right]));
            if (height[left] <= height[right]) {
                left++;
            } else {
                right--;
            }
        }
        return max;
    }
}

42. 接雨水

class Solution {
    public int trap(int[] height) {
        int len = height.length;
        int[] lMax = new int[len];
        lMax[0] = height[0];
        int[] rMax = new int[len];
        rMax[len - 1] = height[len - 1];
        for (int i = 1; i < len; i++) {
            lMax[i] = Math.max(height[i], lMax[i - 1]);
        }
        for (int i = len - 2; i >= 0; i--) {
            rMax[i] = Math.max(height[i], rMax[i + 1]);
        }
        int sum = 0;
        for (int i = 0; i < len; i++) {
            sum += Math.min(lMax[i], rMax[i]) - height[i];
        }
        return sum;
    }
}

407. 接雨水 II

class Solution {
    public int trapRainWater(int[][] heightMap) {
        int m = heightMap.length;
        int n = heightMap[0].length;
        if (m <= 2 || n <= 2) {
            return 0;
        }

        PriorityQueue<int[]> queue = new PriorityQueue<>((o1, o2) -> {
            return o1[1] - o2[1];
        });
        boolean[][] visited = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                // 遍历边界,边界是无法蓄水的,所以都是自身的高度
                if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
                    queue.offer(new int[]{i * n + j, heightMap[i][j]});
                    visited[i][j] = true;
                }
            }
        }
        int[] directs = new int[]{-1, 0, 1, 0, -1};
        int res = 0;
        // 所有节点都需要且只遍历一次
        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            for (int i = 0; i < 4; i++) {
                //+[-1,0],[0,1],[1,0],[0,-1]
                int nx = cur[0] / n + directs[i];
                int ny = cur[0] % n + directs[i + 1];
                if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny]) {
                    if (cur[1] > heightMap[nx][ny]) {
                        res += cur[1] - heightMap[nx][ny];
                    }

                    queue.offer(new int[]{nx * n + ny, Math.max(cur[1], heightMap[nx][ny])});
                    visited[nx][ny] = true;
                }
            }
        }
        return res;
    }
}