当前位置: 首页 > news >正文

22-接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

方法一:双指针法

思路

使用两个指针 left 和 right 分别指向数组的两端,同时记录左边的最大高度 leftMax 和右边的最大高度 rightMax。在每次迭代中,比较 left 和 right 指向的高度,选择较小的一端进行处理。如果 height[left] < height[right],则说明左边的柱子可能会接到雨水,此时计算当前位置能接到的雨水量(leftMax - height[left]),并将 left 指针右移一位;否则,说明右边的柱子可能会接到雨水,计算当前位置能接到的雨水量(rightMax - height[right]),并将 right 指针左移一位。重复这个过程,直到 left 和 right 指针相遇。

代码实现
function trap(height: number[]): number {
    let left = 0;
    let right = height.length - 1;
    let leftMax = 0;
    let rightMax = 0;
    let result = 0;

    while (left < right) {
        if (height[left] < height[right]) {
            leftMax = Math.max(leftMax, height[left]);
            result += leftMax - height[left];
            left++;
        } else {
            rightMax = Math.max(rightMax, height[right]);
            result += rightMax - height[right];
            right--;
        }
    }

    return result;
}

// 示例调用
const height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1];
const rainWater = trap(height);
console.log("下雨之后能接的雨水:", rainWater);

复杂度分析
  • 时间复杂度:(O(n)),其中 n 是数组 height 的长度。因为只需要遍历一次数组。
  • 空间复杂度:(O(1)),只使用了常数级的额外空间。

方法二:单调栈法

思路

使用一个单调栈来存储柱子的索引。遍历数组,对于每个柱子,如果当前柱子的高度大于栈顶柱子的高度,则说明栈顶柱子可以接到雨水,计算并累加接水量,然后将栈顶元素出栈,重复这个过程,直到栈为空或者当前柱子的高度不大于栈顶柱子的高度。最后将当前柱子的索引入栈。

代码实现
function trap(height: number[]): number {
    const stack: number[] = [];
    let result = 0;

    for (let i = 0; i < height.length; i++) {
        while (stack.length > 0 && height[i] > height[stack[stack.length - 1]]) {
            const top = stack.pop();
            if (stack.length === 0) {
                break;
            }
            const distance = i - stack[stack.length - 1] - 1;
            const minHeight = Math.min(height[i], height[stack[stack.length - 1]]) - height[top];
            result += distance * minHeight;
        }
        stack.push(i);
    }

    return result;
}

// 示例调用
const height2 = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1];
const rainWater2 = trap(height2);
console.log("下雨之后能接的雨水:", rainWater2);
复杂度分析
  • 时间复杂度:(O(n)),其中 n 是数组 height 的长度。虽然有一个嵌套的 while 循环,但每个元素最多入栈和出栈一次,所以总的时间复杂度仍然是 (O(n))。
  • 空间复杂度:(O(n)),在最坏情况下,栈中可能会存储所有的柱子索引。

综上所述,双指针法和单调栈法都能有效地解决接雨水问题,双指针法的代码相对简单,空间复杂度较低;单调栈法的思路相对复杂一些,但也能清晰地处理接雨水的逻辑。

相关文章:

  • Deepseek Api Function Calling解析(tools、tool_calls)Deepseek函数调用流程图、Python代码示例
  • 游戏引擎学习第131天
  • 23种设计模式之《备忘录模式(Memento)》在c#中的应用及理解
  • Qt显示一个hello world
  • linux服务器更新jar包脚本
  • 工程化与框架系列(12)--响应式框架原理
  • 2024年12月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析
  • 数据结构课程设计(java实现)---九宫格游戏,也称幻方
  • 热点创意大师智能体
  • 传奇3光通版手游行会战攻略:团队协作与战术布局详解
  • PS通道抠图
  • 推进断裂力学:深入研究工程模拟中的 UMM
  • 10.指针进阶
  • Ragflow与Dify之我见:AI应用开发领域的开源框架对比分析
  • 清华大学Deepseek第六版AIGC发展研究3.0(共186页,附PDF下载)
  • java项目之基于ssm的学籍管理系统(源码+文档)
  • leaflet扩展插件esri-leaflet.js
  • vue3中展示markdown格式文章的三种形式
  • Solana 核心概念全解析:账户、交易、合约与租约,高流量区块链技术揭秘!
  • kan与小波,和不知所云的画图
  • 企业网站制作公司盈利/惠州关键词排名优化
  • 南京网站开发个人/设计网站的软件
  • 巴中建设厅网站电话/互联网创业项目
  • 河南省交通基本建设质量检测监督站网站/名词解释搜索引擎优化
  • 网上做问卷报酬不错的网站是/软文广告投放平台
  • 做网站的图片需要多少钱/qq营销推广方法和手段