如何在 C++ 中使用栈找到直方图中的最大矩形面积?2025年3月24日 | 阅读12分钟 引言要在C++中使用堆栈在直方图中找到最大的矩形面积,我们可以使用一种利用堆栈的特性来有效跟踪直方图条形索引的方法。这种方法确保我们只遍历直方图条形有限次数,从而优化了计算过程。 主要思想是使用堆栈存储直方图条形的索引,以保持递增高度的顺序。当我们遍历直方图时,我们执行以下步骤,如下所示:
方法 1:简单方法实施输出 Maximum rectangular Area is 12 说明初始化结构 遍历直方图
处理递增高度
在高度递减时计算面积
继续遍历
处理剩余索引
输出最大面积
让我们来看一个例子以更好地理解考虑直方图 [6, 2, 5, 4, 5, 1, 6]: 从空堆栈和最大面积0开始。 遍历每个条形
处理剩余索引
因此,最大的矩形面积是12。 复杂度分析时间复杂度 算法的时间复杂度为 O(n),其中 n 是直方图中条形的数量。 单次遍历:算法从左到右对直方图条形进行一次遍历。 压入和弹出操作:每个索引都只被压入堆栈一次,并从堆栈中弹出一次。由于每次压入和弹出操作都需要恒定的时间,因此操作的总数与条形数量成线性关系。 因此,总时间复杂度为 O(n)。 空间复杂度 算法的空间复杂度为 O(n)。以下是详细说明: 堆栈存储:在最坏的情况下,如果所有条形都按递增顺序排列,那么每个条形的索引都会被压入堆栈,这意味着堆栈将包含 n 个索引。 附加变量:附加变量(例如 max_area、i、tp、area_with_top)使用的空间是恒定的,不依赖于输入大小。 因此,总空间复杂度为 O(n)。 方法二:使用分治法这种方法受到了用于查找最大子数组和的算法的启发,它涉及将直方图划分为更小的子问题并递归地求解每个问题。 实施输出 Maximum rectangular Area is 12 说明步骤 1:问题定义 假设你有一个直方图,它由一个条形高度数组表示。你的目标是确定可以在这些条形中形成的最大的矩形面积。 步骤 2:基本情况 最简单的情况是直方图为空,或者你正在检查一个没有条形的范围。在这种情况下,最大的矩形面积为零。 步骤 3:查找最小条形 对于直方图中的任何给定条形范围,识别高度最小的条形。这个条形至关重要,因为:
步骤 4:递归求解子问题 一旦找到了划分直方图的最小条形: 左子直方图:考虑最小条形左侧的条形。递归确定在此左侧部分中可以形成的最大的矩形面积。 右子直方图:同样,考虑最小条形右侧的条形。递归查找此右侧部分的最大的矩形面积。 步骤 5:合并结果 要找到当前范围的整体最大矩形面积:
这三个面积中的最大值是当前条形范围的答案。 步骤 6:递归方法 对于通过查找最小条形创建的每个子直方图,重复上述步骤,直到处理完所有可能的子直方图。 示例让我们将此方法应用于示例直方图 [6, 2, 5, 4, 5, 1, 6]。 初始直方图:从整个条形范围开始。 查找最小条形:范围内的最小条形是索引 5 处的 1。 分而治之
计算面积 左侧部分:[6] 的最大面积为 6,[5, 4, 5] 的最大面积为 9。 右侧部分:[6] 的最大面积为 6。 跨越最小条形的面积:跨越最小条形 1 的面积为 7(高度 1 * 宽度 7)。 这些面积中的最大值是左子直方图 [5, 4, 5] 的 12。 复杂度分析时间复杂度 用于在直方图中查找最大矩形面积的分治法的复杂度可能会因直方图的结构而异。 查找最小条形:每次在子直方图中查找最小条形时,对于整个直方图需要 O(n) 时间,划分后的一侧需要 O(n-1) 时间,依此类推。 递归划分:每次划分都会创建两个新的子问题。在最坏的情况下,如果直方图已经按递增或递减顺序排序,我们可能会进行 n 次递归调用,每次调用都需要 O(n) 时间。 在最坏的情况下,时间复杂度为 O(n)+O(n-1)+O(n-2)+…+O(1)=O(n2) 因此,最坏情况下的时间复杂度为 O(n2)。 空间复杂度 空间复杂度主要由分治法的递归堆栈决定。 递归调用:在最坏的情况下,如果直方图的划分方式使得每个子问题只减少一个元素,那么递归堆栈的深度最多可能为 n。 附加变量:函数中使用的其他变量(例如,用于存储最小索引和计算出的面积)使用恒定空间,不随输入大小缩放。 方法三:使用动态规划法此方法涉及预先计算每个条形结束的最大矩形的宽度,然后使用这些宽度来查找最大面积。 实施输出 Maximum rectangular Area is 12 说明步骤 1:理解问题 你有一个由高度数组表示的直方图,其中数组中的每个元素对应于直方图中条形的高度。目标是确定可以在这些条形中形成的最大的矩形面积。 步骤 2:初始设置 为了有效地查找最大的矩形面积,我们将使用两个数组 left 和 right 来存储每个条形的边界。这些边界将帮助我们确定以每个条形作为最短条形可以形成的最大的矩形的宽度。 步骤 3:查找左边界 对于直方图中的每个条形,我们需要找到其左侧最近的更矮的条形。这有助于我们理解当前条形在保持矩形高度的同时可以向左延伸多远。
步骤 4:查找右边界 对于每个条形,我们还需要找到其右侧最近的更矮的条形。这有助于我们理解当前条形在保持矩形高度的同时可以向右延伸多远。
步骤 5:计算最大面积 确定了每个条形的左侧和右侧边界后,我们现在可以计算每个条形的最大矩形面积,并跟踪整体最大面积。
更新最大面积:将此面积与迄今为止找到的最大面积进行比较,并相应地进行更新。 示例考虑一个高度为 [6, 2, 5, 4, 5, 1, 6] 的直方图 左边界计算
右边界计算
面积计算
找到的最大面积是 12。 复杂度分析时间复杂度 总体时间复杂度: O(n) 左边界计算: O(n),因为每个条形都会被压入和弹出堆栈一次。 右边界计算: O(n),原因相同。 面积计算: O(n),因为它涉及对条形的单次遍历。 空间复杂度 总体空间复杂度: O(n) 辅助数组: O(n) 用于 left 和 right 数组。 堆栈:最坏情况下为 O(n),此时堆栈可以容纳所有条形索引。 因此,动态规划方法的时间复杂度为 O(n),空间复杂度为 O(n)。 下一主题C++ 中的鸡蛋坠落问题 |
简介数学和计算机编程往往是相辅相成的,而可以应用于 C++ 的数学概念之一是中心平方数。在本文中,我们将讨论 C++ 中的中心平方数及其实现和示例。什么是中心平方...
阅读 4 分钟
C++ N元树镜像概述 树是计算机科学和编程中的基本数据结构,因为它们有效地组织和保护分层数据。在许多树种中,N元树是独特的,因为它们可以包含每个父节点的一个以上的子节点……
阅读 6 分钟
在 C++ 中,蹦床(trampolining)是一种主要用于增强递归函数调用过程的技术。递归函数是避免问题复杂性并将其转化为几个更简单问题的有力工具。然而,过度使用深度递归...
阅读 10 分钟
简介:H 指数(H-Index)是指量化给定学者科学表现的指标。它被定义为研究人员发表的至少有“h”篇论文被引用至少“h”次的数量。该产品整合了研究的数量和质量……
14 分钟阅读
“蚂蚁在木板上掉落前的最后一刻”的谜题般的计算挑战吸引了程序员和问题解决者的兴趣。它是那些看似简单实则具有复杂层次的问题之一......
阅读9分钟
简介:Count-Min Sketch 是一种概率数据结构,用于对大型数据流中的近似计数查询。它使用有限的内存空间高效地估计数据流中元素的频率。本质上,Count-Min Sketch 由一个二维计数器数组组成。哈希……
阅读 4 分钟
在本文中,我们将讨论 std::sort() 和 std::stable_sort() 在 C++ 中的区别。在讨论它们的区别之前,我们必须了解 std::sort() 和 std::stable_sort() 的语法、参数和示例。什么是 C++ 中的 std::sort() 函数? 在 C++ 编程中,std::sort() 函数是……
阅读 4 分钟
本文讨论了 C++ 和 Ada 之间的区别。在理解区别之前,让我们先了解一下各自。C++ 是什么?C++ 是 Bjarne Stroustrup 于 1985 年开发的,作为 C 编程语言的增强版,旨在为开发人员提供高级抽象……
阅读 4 分钟
简介 本文的主要主题是 C++ 中的 std::exponential_distribution 类,它是标准库中用于生成指数分布随机数的相当有用的工具。当关注泊松过程中事件之间的时间时,这种分布很有应用价值……
阅读 6 分钟
在本文中,我们将讨论带实现。简介:纸牌翻转游戏是一种简单但有趣的游戏,玩家将牌面朝下放在网格中进行翻转。此游戏的目标是通过一次翻转两张牌来找到匹配的对...
阅读 6 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India