C++ 中的接雨水2025年5月13日 | 阅读 9 分钟 引言在 C++ 中,盛水问题 是一个经典的算法问题,涉及高效计算由给定数组表示的地形中可以盛放的水量。目标是找到累积的水量单位。解决方案通常采用双指针或动态规划技术。首先遍历数组以识别潜在的盛水位置,并使用左右指针跟踪从两端遇到的最高条形。然后,根据封闭条形的高度最小值计算每个位置的水位。将这些水位相加即可获得最终结果。 程序输出 Trapped Water: 6 说明
代码首先检查输入数组 height 的大小是否小于或等于 2。如果为真,则返回 0,因为没有足够的条形来盛水。
创建两个附加数组 leftMax 和 rightMax,分别用于存储从左边和右边遇到的最大高度。 通过从左到右遍历输入数组来填充 leftMax 数组,更新每个位置遇到的最大高度。 类似地,通过从右到左遍历来填充 rightMax 数组。
然后,循环遍历输入数组中的每个位置。 对于每个位置,它通过查找左右两边的最大高度 (leftMax 和 rightMax) 之间的最小高度,然后减去当前条形的高度来计算盛水量。 结果是将所有位置的这些盛水量相加得到的总和。
最终结果(表示总盛水量)将被打印出来,或者可以根据需要进一步使用。 复杂度分析 时间复杂度 代码的时间复杂度为 O(n),其中 n 是输入数组 height 的大小。 循环遍历数组三次:一次用于计算左最大值,一次用于计算右最大值,一次用于计算盛水量。每次迭代都涉及对数组的线性扫描。 空间复杂度 空间复杂度为 O(n)。 为两个数组(leftMax 和 rightMax)使用了额外的空间,每个数组的大小为 n,用于存储每个位置从左边和右边遇到的最大高度。 这些数组使用的空间与输入数组的大小成正比。 方法一:使用双指针使用双指针,一个从数组的开头开始,另一个从数组的结尾开始。然后,在保持从左边和右边遇到的最大高度的同时,将指针相互移动。 程序输出 Trapped Water: 6 说明
两个指针 left 和 right 分别在输入数组 height 的开头和结尾初始化。 两个变量 leftMax 和 rightMax 初始化为跟踪从左边和右边遇到的最大高度。 另一个变量 trappedWater 初始化为跟踪总盛水量。
主循环运行,直到左指针小于右指针,确保它们向彼此收敛。
如果左指针处的高度小于右指针处的高度 使用其当前值和左指针处高度的最大值更新 leftMax。 根据 leftMax 和左指针处高度之间的差值,计算并添加左指针处的盛水量。 将左指针向右移动。 如果左指针处的高度大于或等于右指针处的高度(或它们相等) 使用其当前值和右指针处高度的最大值更新 rightMax。 根据 right mix 和右指针处高度之间的差值,计算并添加右指针处的盛水量。 将右指针向左移动。
最终结果是循环完成后累积的 trappedWater。 复杂度分析 时间复杂度 时间复杂度为 O(n),其中 n 是输入数组 height 的大小。 该算法对数组进行一次遍历,在每一步,左指针或右指针都会向中心移动。当指针相遇时,循环终止。 空间复杂度 空间复杂度为 O(1),表示常量空间使用。 该算法使用的变量数量是固定的(left, right, leftMax, rightMax, trappedWater),与输入数组的大小无关。它不需要与输入大小成比例的额外空间。 方法 2:使用栈使用栈来跟踪条形的索引。栈将按高度非递减的顺序存储条形的索引。 遍历高度数组,并为每个条形确定它贡献的盛水量。 如果当前条形的高度大于栈顶条形的高度,则从栈中弹出元素并计算盛水量,直到遇到高度更大或相等的条形。 程序输出 Trapped Water: 6 说明
我们首先初始化两个变量:trappedWater 用于跟踪总盛水量,以及一个栈 st 用于存储条形的索引。
我们遍历高度数组,逐个处理每个条形。 对于每个条形,我们检查栈是否为空,或者当前条形的高度是否小于或等于栈顶条形的高度。 如果为真,我们将当前条形的索引推入栈中。 如果为假,则表示当前条形的高度大于栈顶条形的高度,表明存在潜在的盛水位置。 我们进入一个循环,只要栈不为空且当前条形的高度大于栈顶条形的高度,我们就从栈中弹出元素。 在弹出时,我们计算每个弹出条形的盛水量,并相应地更新 trappedWater。 每个弹出条形的盛水量是根据当前条形和栈顶条形之间的距离,乘以当前条形和弹出条形之间高度的差值来计算的,同时考虑两个高度中的较低者。
处理完所有条形后,循环终止。 我们返回 trappedWater 的最终值,它表示地形中的总盛水量。 复杂度分析 时间复杂度 时间复杂度为 O(n),其中 n 是输入数组 height 中的条形数量。 最坏情况下,每个条形只处理一次。在每次迭代中,从栈中推送和弹出元素等操作需要恒定的时间。 空间复杂度 空间复杂度为 O(n),其中 n 是输入数组 height 中的条形数量。 栈在最坏情况下最多可以存储所有条形。此外,其他变量(trappedWater、循环索引)需要恒定的空间。 总空间使用量随输入数组中条形数量的增加而线性增长。 方法三:使用动态规划预先计算每个条形从左边和右边的最大高度,存储在两个单独的数组中。 通过考虑左右边界最大高度的最小值来计算每个条形的盛水量。 程序输出 Trapped Water: 6 说明
我们首先初始化两个数组 leftMax 和 rightMax,分别用于存储每个条形从左边和右边遇到的最大高度。 这些数组的大小与输入数组 height 相同。
我们通过从左到右遍历输入数组 height 来填充 leftMax 数组。 对于每个条形,我们将该位置的 leftMax 值更新为当前值和当前条形高度的最大值。 这个过程确保 leftMax[i] 存储了索引 i 处的条形从左边遇到的最大高度。 类似地,我们通过从右到左遍历输入数组 height 来填充 rightMax 数组。 对于每个条形,我们将该位置的 rightMax 值更新为当前值和当前条形高度的最大值。 这个过程确保 rightMax[i] 存储了索引 i 处的条形从右边遇到的最大高度。
一旦我们计算了左右边界的最大高度,我们就遍历输入数组 height。 对于索引 i 处的每个条形,我们计算该位置的盛水量 我们取 leftMax[i] 和 rightMax[i] 的最小值,这代表当前条形从左右边界的最大高度的最小值。 我们从这个最小值中减去当前条形 height[i] 的高度,得到该位置盛水的高度。 这个高度代表了当前条形可以盛放的水量。 我们累加所有条形的盛水量,得到总盛水量。 返回结果 最后,我们返回上一步计算的总盛水量。 复杂度分析 时间复杂度 时间复杂度为 O(n),其中 n 是输入数组 height 中的条形数量。 对输入数组进行了两次遍历:一次用于计算从左边的最大高度,一次用于计算从右边的最大高度。 此外,对输入数组进行一次遍历,以计算每个条形的盛水量。 总的来说,时间复杂度仍然与输入数组中的条形数量成线性关系。 空间复杂度 空间复杂度为 O(n),其中 n 是输入数组 height 中的条形数量。 为两个数组(leftMax 和 rightMax)使用了额外的空间,每个数组的大小为 n,用于存储每个条形从左右边界的最大高度。 空间使用与输入数组的大小成正比,但它不随输入数组的大小而增长。 总的空间复杂度仍然与输入数组中的条形数量成线性关系。 |
阿达姆数是指一个数 n,其平方与其反序数的平方互为反序。阿达姆数是这样一个数,其反序数的平方等于其反序的...
阅读 4 分钟
在本文中,我们将讨论。在讨论之前,我们必须了解方法和示例。什么是惊人数字?惊人数字的概念在编程和数论中都很有趣。N 是一个数字,当除以二时满足特定要求...
5 分钟阅读
在本文中,您将通过几个示例了解如何使用 C++ 中的 DSU 检测图中的循环。图:图是由节点(顶点)和连接节点对的边组成的集合。图可以是定向的或非定向的,并且可以分配权重……
阅读20分钟
超级 D 数是不同的数字,当其所有数字都增加到 D 的给定幂时,其和等于数字本身。对于数字 N,它满足数学公式 N=∑diD,其中 di 是 N 的数字。例如,153 是...
5 分钟阅读
在本文中,我们将讨论其语法、参数和示例。C++ 中的 std::tmpnam() 是什么?在 C++ 中,有一个函数可以创建唯一的文件名,那就是 std::tmpnam。“Tmpnam”是“临时名称”的缩写。它主要用于 C++...
阅读 4 分钟
引言 在黄金比例之后,Wythoff 序列是组合博弈论中用于玩家移动的数学组合。它以 Willem Abraham Wythoff 的名字命名,他根据具有与黄金分割的奇特关系的斐波那契数列创建了一个序列。在这个...
阅读 15 分钟
概述:给定 n 根不同长度的绳子,需要将所有绳子合并成一根。合并任意两根绳子将产生等于两根绳子之和的成本。目标是最小化合并所有绳子的成本....
阅读 4 分钟
C++ 和 COBOL 都是高级编程语言。C++ 用于系统级编程和开发高度复杂的应用程序。另一方面,COBOL 在公司和政府的业务和财务管理中仍然更广泛地使用。当...
5 分钟阅读
在本文中,我们将讨论如何在 C++ 中找到引爆所有气球所需的最少箭数。问题陈述:给定一个大小为 N 的数组,其中 points[i] 表示覆盖 X 坐标中 points[i][0] 和 points[i][1] 区域的气球....
阅读 4 分钟
引言:在C++中,适当的内存管理对于整体一致性和程序性能至关重要,尤其是在开发资源密集型程序时。标准内存库提供了一系列函数来控制动态内存分配和释放,以协助完成此任务。std::return_temporary_buffer是其中一个工具,它……
阅读 6 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India