代码随想录算法训练营Day55|42.接雨水、84.柱状图中最大的矩形

5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

接雨水

42. 接雨水 - 力扣(LeetCode)

暴力解法

对计算接到的雨水,有两种方式,一是按照行来计算。

另一种是按列计算

按列计算容易不乱。基本思路如下:

对每列i进行循环,在循环中,找到该列左侧的最大高度leftHeight和该列右侧的最大高度rightHeight,该列能接到的雨水为两者较小值减去该列的高度。

h = min(leftHeight,rightHeight) - height[i] 

当h大于0时,将结果累加进最后的返回结果result中.

具体思路可以看代码随想录 (programmercarl.com)

代码如下

class Solution {
public:
    //计算给定高度数组中能接的雨水量
    int trap(vector<int>& height) {
        int sum = 0; // sum 用于累计接到的雨水量
        for(int i = 0; i < height.size(); i++){ // 遍历数组中的每个元素
            if(i == 0 || i == height.size() - 1) // 数组的第一个和最后一个元素不能接雨水
                continue; // 跳过这两个元素
            int rightHeight = height[i]; // 右边最高的柱子高度,初始设为当前柱子高度
            int leftHeight = height[i]; // 左边最高的柱子高度,初始设为当前柱子高度
            for(int r = i + 1; r < height.size(); r++){ // 向右扫描,找到右边最高的柱子
                if(height[r] > rightHeight)
                    rightHeight = height[r];
            }
            for(int l = i - 1; l >= 0; l--){ // 向左扫描,找到左边最高的柱子
                if(height[l] > leftHeight)
                    leftHeight = height[l];
            }
            int h = min(leftHeight, rightHeight) - height[i]; // 计算当前位置可以接的雨水量
            if(h > 0)
                sum += h; // 如果可以接雨水,则加到总雨水量上
        }
        return sum; // 返回总的接雨水量
    }
};

算法的时间复杂度为O(n^2),对于每个元素都要向左右遍历一次获取最大的leftheight和rightheight,最后2个案例会超时,ac不了,空间复杂度为O(1)。

双指针法

在上述的暴力解法中,如果我们进行调试的话,会发现每次的运行都会左右遍历一次以获取最大的leftheight和rightheight,而这有很多的计算浪费,所以我们可以在开始就从左到右,从右到左遍历一次数组,得到两个数组,分别表示每列i的leftheight和rightheight,然后用上述计算h的方法再计算一次,将算法的时间复杂度降为O(n)。

class Solution {
public:
    int trap(vector<int>& height) {
        int sum = 0;
        vector<int> leftHeight(height.size(), 0); // 创建一个数组来存储每个位置的左边最高柱子高度
        vector<int> rightHeight(height.size(), 0); // 创建一个数组来存储每个位置的右边最高柱子高度
        int maxHeight_left_temp = height[0]; // 初始化左边最高柱子高度为第一个元素的高度
        int maxHeight_right_temp = height[height.size() - 1]; // 初始化右边最高柱子高度为最后一个元素的高度
        for (int i = 1; i < height.size(); i++) {
            maxHeight_left_temp = max(maxHeight_left_temp, height[i]); // 更新左边最高柱子高度
            leftHeight[i] = maxHeight_left_temp; // 存储左边最高柱子高度
        }
        for (int i = height.size() - 2; i >= 0; i--) {
            maxHeight_right_temp = max(maxHeight_right_temp, height[i]); // 更新右边最高柱子高度
            rightHeight[i] = maxHeight_right_temp; // 存储右边最高柱子高度
        }

        // 再次遍历数组,计算每个位置可以接的雨水量
        for (int i = 0; i < height.size(); i++) {
            int h = min(leftHeight[i], rightHeight[i]) - height[i]; // 计算当前位置可以接的雨水量
            if (h > 0)
                sum += h; // 如果可以接雨水,则加到总雨水量上
        }

        return sum;
    }
};

算法的时间复杂度为O(n),空间复杂度为O(n)(2个长度为n的数组),以空间换时间。

单调栈法

这里想像这样一个问题,接雨水即需要找到当前柱子右侧的大于等于该柱子高度的柱子,然后计算接到的雨水,因此,可以使用单调栈法。

从左到右遍历时,需要找到比当前元素大的元素,考虑使用单调递增栈(什么问题使用什么栈参考之前day52的文章)

class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> st; // 创建一个栈来存储柱子的索引
        int sum = 0; // sum 用于累计接到的雨水量
        st.push(0); // 先将第一个柱子的索引入栈

        for (int i = 1; i < height.size(); i++) { // 从第二个柱子开始遍历数组
            if (height[i] < height[st.top()]) { // 如果当前柱子高度小于栈顶柱子高度
                st.push(i); // 将当前柱子的索引入栈
            } else if (height[i] == height[st.top()]) { // 如果当前柱子高度等于栈顶柱子高度
                st.pop(); // 弹出栈顶元素
                st.push(i); // 将当前柱子的索引入栈
            } else { // 如果当前柱子高度大于栈顶柱子高度
                while (!st.empty() && height[i] > height[st.top()]) { // 当栈不为空且当前柱子高度大于栈顶柱子高度时
                    int mid = st.top(); // 获取栈顶柱子的索引
                    st.pop(); // 弹出栈顶元素
                    if (!st.empty()) { // 如果栈不为空
                        int h = min(height[st.top()], height[i]) - height[mid]; // 计算凹槽的高度
                        int w = i - st.top() - 1; // 计算凹槽的宽度
                        sum += h * w; // 计算凹槽可以接的雨水量,并加到总雨水量上
                    }
                }
            }
            st.push(i); // 将当前柱子的索引入栈
        }

        return sum; // 返回总的接雨水量
    }
};

算法的时间复杂度为O(n),空间复杂度为O(n)。

柱状图中最大的矩形

84. 柱状图中最大的矩形 - 力扣(LeetCode)

暴力解法

类似上题的想法,对每个列i找到左方第一个高度小于它的列left和右方第一个高度小于它的列right,面积为(right - left - 1) *  heights[i]。同样,算法的时间复杂度为O(n^2),空间复杂度为O(1)。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int sum = 0; // sum 用于存储最大矩形面积
        for (int i = 0; i < heights.size(); i++) { // 遍历数组中的每个元素
            int left = i; // 初始化左边边界为当前柱子
            int right = i; // 初始化右边边界为当前柱子

            // 向左扫描,找到左边第一个高度小于当前柱子的位置
            for (left = i; left >= 0; left--) {
                if (heights[left] < heights[i]) break;
            }

            // 向右扫描,找到右边第一个高度小于当前柱子的位置
            for (right = i; right < heights.size(); right++) {
                if (heights[right] < heights[i]) break;
            }

            // 计算以当前柱子为高的矩形面积
            int w = right - left - 1; // 矩形的宽度
            int h = heights[i]; // 矩形的高,即当前柱子的高度
            sum = max(sum, w * h); // 更新最大矩形面积
        }
        return sum; // 返回最大矩形面积
    }
};

超时。

双指针法

有些难度,参考代码随想录代码随想录 (programmercarl.com)

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        vector<int> minLeftIndex(heights.size());
        vector<int> minRightIndex(heights.size());
        int size = heights.size();

        // 记录每个柱子 左边第一个小于该柱子的下标
        minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环
        for (int i = 1; i < size; i++) {
            int t = i - 1;
            // 这里不是用if,而是不断向左寻找的过程
            while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t];
            minLeftIndex[i] = t;
        }
        // 记录每个柱子 右边第一个小于该柱子的下标
        minRightIndex[size - 1] = size; // 注意这里初始化,防止下面while死循环
        for (int i = size - 2; i >= 0; i--) {
            int t = i + 1;
            // 这里不是用if,而是不断向右寻找的过程
            while (t < size && heights[t] >= heights[i]) t = minRightIndex[t];
            minRightIndex[i] = t;
        }
        // 求和
        int result = 0;
        for (int i = 0; i < size; i++) {
            int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);
            result = max(sum, result);
        }
        return result;
    }
};

算法的时间复杂度为O(n),空间复杂度也为O(n)。

单调栈法

代码随想录 (programmercarl.com)

明天补

魔兽世界怀旧服宏命令全解析:从自动换装到智能判定,老玩家才知道的黑科技 本文全面解析魔兽世界怀旧服宏命令的高级应用,从自动换装到智能判定,揭秘老玩家专属的黑科技技巧。深入探讨怀旧服特有的宏命令机制,包括施法队列、装备切换系统和职业专属技巧,帮助玩家在经典旧世版本中提升战斗效率。 阅读详情

相关推荐

Simulink中通过MEX与MinGW实现C/C++结构体变量的高效导入

本文详细介绍了在Simulink中通过MEX工具链与MinGW编译器,高效导入C/C++结构体变量的完整流程。文章从需求背景出发,逐步讲解了MinGW环境配置、.h文件编写规范、核心导入命令Simulink.importExternalCTypes的使用,以及如何在MATLAB Function模块和总线创建器中调用自定义结构体,旨在实现模型与代码的无缝对齐,为后续仿真和代码生成奠定坚实基础。

weixin_29056781的博客 341

笔记:代码随想录算法训练营day55:LeetCode42. 接雨水、84.柱状图中最大的矩形

单调栈:遇到比栈顶小的值和等于的值就入栈,相当于等待那个大的出现,如次栈顶的下一个下标对应的值比它大,再遇到大的,正好栈顶元素的两边会比其大。先看单调栈的方法:首先要理解求这个面积的方法是当前的值为高,宽为左边比其小到右边比其小的这个距离,高乘宽为能勾勒的最大矩形的面积。这次是找两边的小值,逻辑上是接雨水变一下操作逻辑,当前大于等于栈顶的情况入栈,等那个小的,这样栈顶两侧都比其小。这次双指针也是记录的下标了,而且和上一题不同的一个地方是,不是找两侧的最小的,而是找到第一个比其小的就停。

jingjingjing1111的博客 444

一文带你了解SOA接口测试

了解汽车电子行业的人,近几年可能经常见到一个词“SOA”,那SOA具体是什么?作为测试人员应该要测试哪些内容呢?这篇文章就简单给大家介绍一下。SOA(Service Oriented Architecture)是一种面向服务的架构,最早应用于IT行业,虽然行业内对于SOA的定义没有一个统一的描述,但是总体而言,SOA把功能定义成为服务,服务带有明确的可调用接口,并可以通过网络调用。在汽车领域,对于高性能计算平台而言,为了实现域控制器以及区域控制器之间的互联互通和软硬分离、缩短开发周期等优势,也引入了SOA的

怿星科技的博客 7154

代码随想录算法训练营DAY55|42. 接雨水、84.柱状图中最大的矩形

【代码】代码随想录算法训练营DAY54|42. 接雨水、84.柱状图中最大的矩形。

Greeneril_的博客 386

电机控制中ADC采样时序的优化策略与实践

本文深入探讨了电机控制中ADC采样时序的优化策略与实践,重点分析了BLDC和FOC控制方案中的核心挑战与解决方案。通过硬件布局优化、软件滤波技术及动态时序补偿等方法,有效提升电流采样精度和系统稳定性,为电机控制系统的性能优化提供实用指导。

weixin_42519985的博客 386

《数据结构》02-线性结构1 两个有序链表序列的合并

题目 本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。 函数接口定义: List Merge( List L1, List L2 ); 其中List结构定义如下: typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next;...

叫我皮卡丘 7662

【代码随想录】【算法训练营】【第55天】 [42]接雨水 [84]柱状图中最大的矩形

思路及算法思维,指路。题目来自。day 55,又是一个周一,不能再坚持~

day day up 682

CSP-J 入门级第一轮认证 2025 详细解析

2025年CSP-J入门级第一轮认证模拟赛提供10套免费试题,含选择题与解析。选择题涉及计算机科学基础,如32位无符号整数最大值计算(约42.9亿,选A)、C++位运算(255&254=254,选B)、递归函数分析(calc(5)=6,选B)、哈夫曼树构造(带权路径长度186,选B)等。其他题目涵盖图论(有向图边数等于入度/出度和,选B)、组合数学(120种选法,选C)、布尔逻辑(选项C不恒等)、模运算周期性(f[2025]=6,选D)、C++字符串特性(支持string+char,选B)及引用传参

lan_in的博客 2939

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 15

1 FFmpeg从入门到精通-FFmpeg简介

1.FFmpeg简介 1.1 FFmpeg的定义 1.2 FFmpeg的历史 1.3 FFmpeg的基本组成 1.4 FFmpeg的编解码工具ffmpeg 1.5 FFmpeg的播放器ffplay 1.6 FFmpeg的多媒体分析器ffprobe 1.7 FFmpeg编译(1)FFmpeg之Windows平台编译(2)FFmpeg之Linux平台编译(3)FFmpeg之OS X平台编译 1.8 FFmpeg编码支持与定制(1)FFmpeg的编码器支持(2)FFmpe

migu123的专栏 3684

【Python爬虫】股票信息定向爬取

【Python爬虫】股票信息定向爬取:通过requests-bs4-re技术路线爬虫获取上交所和深交所所有股票的名称和交易信息

qq_39321802的博客 1500

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 437

uniapp - 实现手机端H5网页直播功能效果,拿到后端推流地址或播放资源后进行前端的流畅播放和画面展示功能,uniapp实时推流/拉流直播系统详细教程(提供完整示例代码,一键复制开箱即用!)

uniapp,h5网页,手机端H5网页,uniapp h5直播功能页面,uniapp直播实时推送显示,uniapp h5直播怎么做,怎么使用uniapp去实现移动端手机H5直播,h5 vue+uniapp怎么做直播,uniapp中使用videojs构建H5直播播放器,uniappH5端怎么实现直播推流,uniapp如何实现直播,直播聊天功能,h5平台端直播用什么插件,uniapp手机网页直播用什么组件插件播放器,uniapp手机H5直播播放器详细教程,直播项目,怎么使用vue+uniapp怎么做H5实时直播

✅ 精选推荐文章 8792

【算法拾光】模拟|外观数列 + 数青蛙

本文总结两道模拟题解法:外观数列通过迭代统计连续数字个数生成下一项,关键在于处理末尾字符;数青蛙则模拟青蛙叫声“croak”状态转移,维护各阶段青蛙数量,记录最大并发数并确保全部完成。共性在于严格遵循流程、细致处理边界与非法情况,锻炼字符串遍历与状态管理能力。

wuqingyigexiaoba的博客 362

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 77

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

AI和大模型—从克里金算法说开去

克里金算法源于矿业勘探,通过空间自相关性实现稀疏数据下的最优预测,核心优势在于不确定性量化。在AI大模型中,其等价于高斯过程,广泛应用于超参数优化、小样本建模与推理调度。尽管面临计算复杂度高、核函数选择难等问题,通过稀疏化、分治法与低秩近似可有效优化。该方法在降低训练成本、提升泛化能力及减少幻觉方面表现突出,尤其适用于高维、高成本的智能系统优化,具有重要借鉴价值。

fpcc的专栏 602

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

算法日常・每日刷题--<动态规划>32

给定严格递增的正整数数组,求最长斐波那契子序列长度。使用二维DP,dp[i][j]表示以arr[i]、arr[j]为最后两项的序列长度,初始化均为2。通过哈希表快速查找前一项target = arr[j] - arr[i],若存在且下标小于i,则状态转移:dp[i][j] = dp[k][i] + 1。遍历更新全局最大长度,最终若结果小于3则返回0。时间复杂度O(n²),空间复杂度O(n²)。

2503_92261635的博客 176

算法札记:几何分布在算法题UVA1262的运用

集卡问题求解核心:将集齐n种优惠券的过程分为n个阶段,每个阶段期望购买次数为 $ \frac{n}{k} $(k为剩余种类数),总期望为 $ n \cdot H_n $(调和数)。通过自洽方程推导单阶段期望,无需几何分布或无穷级数,逻辑清晰且适用于大一水平。例如,n=5时期望约11.42,非5。题目要求以带分数形式输出精确结果,算法上需累加分数并化简。

Keven_11的博客 307

不同的二叉搜索树

互不相同的二叉搜索树的种数,以 j (1<=j<=i)为头节点,左子树是 j-1 个数,右子树就是 i - (j - 1) -1 = i - j个数。所以dp[3] = dp[0] * dp[2] + dp[1] * dp[1] + dp[2] * dp[0]头1 = 左子树0节点 * 右子树2节点,二叉搜索树就是排序树,左子树<根节点<右子树,左右子树也满足左子树<根节点<右子树。头2 = 左子树1节点 * 右子树1节点。所以dp[i] += dp[j-1] * dp[i-j]个节点组成且节点值从。

qq_44721738的博客 150

SSL证书选RSA还是ECDSA:公钥算法、CA签名与兼容性怎么核对

申请SSL证书时,RSA和ECDSA该怎么选?先分清站点公钥算法、CA签名算法和TLS实际兼容性,再用隔离OpenSSL实验读取两类材料,核对申请、续期和部署交接,避免只看Signature Algorithm就选错。

谁呀!的博客 381

固件开发岗算法

背景:嵌入式固件岗,偏爱手写库函数、位运算、数组基础算法。

2502_90352018的博客 109

从曲线到储层:Techlog/KAPPA 全流程算法、UltraLAB 选型与本地 AI 部署实战

以高频 CPU 保证交互,以充足内存承载多井与多任务,以 NVMe 打通项目和知识库 I/O,再按本地模型、上下文与并发配置 GPU。对 UltraLAB 用户而言,更合理的采购方式是带着真实项目做选型:一组典型井、一套完整解释模板、一个目标大模型、一次多人并发测试。用实测结果确定配置,才能把预算转化为解释效率,而不是闲置算力。软件模块、操作系统与许可条件以厂商当前正式说明为准;硬件建议需结合项目实测。AI 输出只能作为辅助证据,不能替代岩石物理与油藏工程专业审核。

wdf8088的博客 161

【Deep-OC-SORT 01】多轨迹算法Deep-OC-SORT源码分析

本工程基于Deep-OC-SORT核心模块,重构并适配了EmbeddingComputer(外观特征提取)、CMCComputer(相机运动补偿)与OCSort(主跟踪器)三类。前者实现整框/网格模式的特征提取与L2归一化;后者通过稀疏光流或SIFT匹配估计仿射变换,补偿相机运动;主跟踪器融合IoU、外观相似度与方向一致性,支持模块开关与自定义组件,实现高效多目标跟踪。

Jayson 博客 330

C++ 标准库算法全景指南

本文系统梳理C++标准库<algorithm>与<numeric>中100+算法,按功能分为非修改、修改、排序、二分查找、归并、堆、极值、字典序、排列及数值操作十大类,涵盖典型用法与时间复杂度。结合C++20范围(ranges)与投影特性,实现更简洁高效的代码。

sss123ddd的博客 232

高速公路无人机巡检系统:场景、算法与部署方案

高速公路巡检的工程矛盾,不在“能不能飞到”,而在“端侧算力、时延约束与精度要求三者之间如何分配”。路面病害要求毫米级识别,但高速动态成像与运动模糊压制了单帧精度;交通事件要求秒级推送,但隧道与峡谷的通信盲区切断了云端链路;桥梁梁底的无卫星信号环境,则把自主定位的难度推到了GNSS失效的边界。本文从“端—边—云”三级协同的工程逻辑出发,拆解路面病害、交通事件、桥梁结构三类场景下算法与部署的实际取舍,结合重庆绕城高速、广西六宾高速、南京6G低空巡检等公开数据,给出可复用的系统设计参考。

THJS优快云的博客 192

Consistent-Point半监督人群计数算法详解

本文首次指出并量化了点定位半监督人群计数中伪点的位置不一致与类别不一致问题(Mean-Teacher baseline 甚至不如只用标注数据),并给出两个极简正交模块——PA 用"被匹配的伪点与其邻近提议点定位相似"的洞察做空间平均,以 1/K 方差收缩稳住位置;IUC 用分类得分做实例级加权,压低决策边界附近模糊伪点的监督强度。两模块零推理开销、只引入一个超参 λ,在 5 数据集 × 3 标注比例的 15 个定位设置上全部 SOTA,并在 CPS 框架上验证泛化性,说明"伪标签一致性"是点定位半监督范式中

Keep_Trying_Go的博客 320
上一篇: 代码随想录算法训练营Day53|739.每日温度、496.下一个最大元素I、503.下一个更大元素II
下一篇: 代码随想录算法训练营Day56|所有可达路径、797.所有可能的路径
viaNoir
博客等级 码龄10年 535粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值