LeetCode挑战:最大化水容器面积

需积分: 0 0 下载量 130 浏览量 更新于2024-08-04 收藏 26KB DOCX 举报
"LeetCode题目Container With Most Water的讨论与解决方案" 在LeetCode的这道题“Container With Most Water”中,目标是找到非负整数数组`a1, a2, ..., an`中的两个下标i和j,使得以这些下标对应的值`ai`和`aj`作为容器的两边,X轴作为底部,形成的容器能容纳最多的水。问题转化为求解`|i - j| * min(ai, aj)`的最大值。 初级解法是简单的暴力枚举,时间复杂度为O(n^2)。对所有可能的(i, ai)和(j, aj)组合进行比较,选取最大的面积。然而,这种方法在数据量较大时会导致超时。 中级思路则考虑优化算法。注意到当最大容量由(i, a)和(j, b)决定时,有以下两个关键性质: 1. 如果存在坐标(j + k, c),其中k > 0,那么b > c。这是因为若b ≤ c,则(i, a)和(j + k, c)形成的面积(k + j - i) * min(a, c)将大于(i, a)和(j, b)形成的面积(j - i) * min(a, b)。因此,对于最大容量,b一定是当前所有右边坐标中的最大值。 2. 同样的逻辑适用于a和左侧坐标的关系,a应是所有左边坐标中的最大值。 基于这两个性质,我们可以先进行一次预处理,标记出所有比左侧坐标大的坐标和比右侧坐标大的坐标,这样可以快速定位到当前的最大左侧值和右侧值。预处理的时间复杂度为O(n)。 在求解过程中,可以从两端开始遍历,即i从0开始,j从数组长度减1开始,只考虑标记过的坐标值。这样有效地减少了无效的计算,降低了时间复杂度,使算法在大数据集上也能运行。 以下是中级思路的C++代码实现片段: ```cpp class Solution { public: int maxArea(vector<int>& height) { int max_area = 0; vector<int> left_flag, right_flag; // 预处理,标记左右边界 // ... // 从两端开始遍历,i和j只取标记过的值 for (int i = 0, j = height.size() - 1; i < j; i++, j--) { // 计算当前面积并更新最大值 max_area = max(max_area, abs(i - j) * min(height[i], height[j])); } return max_area; } }; ``` 通过这样的优化,我们能够有效地解决这个问题,并在LeetCode的大规模数据测试用例中通过。这种方法展示了动态规划和贪心策略在解决这类问题时的强大能力。