代码训练LeetCode(38)盛最多水的容器

代码训练(38)盛最多水的容器

Author: Once Day Date: 2025年6月22日

漫漫长路,才刚刚开始…

全系列文章可参考专栏: 十年代码训练_Once-Day的博客-优快云博客

参考文章:

1. 原题

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0)(i, height[i])

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

**说明:**你不能倾斜容器。

提示:

  • n == height.length
  • 2 <= n <= 105
  • 0 <= height[i] <= 104

示例 1:

在这里插入图片描述

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

输入:height = [1,1]
输出:1
2. 分析

这道题目其实是一个非常经典的问题,在算法中称为“盛最多水的容器”。给定一个数组 height,数组中的每个元素代表垂直线的高度,数组的索引表示垂直线的位置。我们需要找到两根线,这两根线与 x 轴形成的容器可以容纳最大量的水。

一个直观的方法是使用双重循环枚举所有可能的线对,计算它们构成的容器的容积,然后找出最大值。但这种方法的时间复杂度是 O(n^2),对于较大的 n 来说效率不高。

一个更高效的办法是使用双指针技术:

  1. 初始化两个指针,一个指向数组的开始(left),一个指向数组的结束(right)。
  2. 计算当前两个指针指向的线构成的容器的容积,并更新最大容积。
  3. 移动两个指针中指向较矮线的那一个(因为容器的容积受到较矮的线的限制,希望找到可能更高的线以增加容积)。
  4. 重复步骤2和3,直到两个指针相遇。

以数组 height = [1, 8, 6, 2, 5, 4, 8, 3, 7] 为例:

  • 初始化:left = 0, right = 8,最大容积 max_area = 0
  • 计算容积:min(height[left], height[right]) * (right - left) = min(1, 7) * (8 - 0) = 7
  • 移动 left 指针(因为 height[left] < height[right]
  • 这样的操作持续进行,直到 leftright 相遇。

性能优化关键点:

  • 时间复杂度: 双指针方法将时间复杂度降低到 O(n)。
  • 空间复杂度: O(1),因为除了输入数组外没有使用额外的空间。
3. 代码实现
#include <stdio.h>

int maxArea(int* height, int heightSize) {
    int left = 0, right = heightSize - 1;
    int max_area = 0;
    while (left < right) {
        int width = right - left;
        int h = height[left] < height[right] ? height[left] : height[right];
        int current_area = width * h;
        if (current_area > max_area) {
            max_area = current_area;
        }
        if (height[left] < height[right]) {
            left++;
        } else {
            right--;
        }
    }
    return max_area;
}

int main() {
    int height[] = {1, 8, 6, 2, 5, 4, 8, 3, 7};
    int n = sizeof(height) / sizeof(height[0]);
    int result = maxArea(height, n);
    printf("最大储水量是: %d\n", result);
    return 0;
}
4. 总结

这个问题考验了对双指针技术的理解和应用,是一个在面试中常见的问题。通过这种问题,可以提升对数组和指针操作的熟悉度,以及如何优化问题的解法以达到更高效的算法实现。在实际编程中,了解并应用各种算法和数据结构是非常重要的,可以通过类似问题的练习来加深理解和应用能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值