33-盛最多水的容器

news/2025/3/28 8:23:13/

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

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

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

说明:你不能倾斜容器。

方法一:暴力枚举法

该方法通过遍历数组中所有可能的两条线的组合,计算它们所构成容器的水量,然后找出其中的最大值。

function maxArea(height: number[]): number {let maxWater = 0;const n = height.length;for (let i = 0; i < n; i++) {for (let j = i + 1; j < n; j++) {const width = j - i;const minHeight = Math.min(height[i], height[j]);const water = width * minHeight;maxWater = Math.max(maxWater, water);}}return maxWater;
}
复杂度分析
  • 时间复杂度:(O(n^2)),因为需要使用两层嵌套循环来遍历所有可能的线对,n 是数组的长度。
  • 空间复杂度:(O(1)),只使用了常数级的额外空间来存储最大水量。

方法二:双指针法

使用两个指针分别指向数组的首尾,计算当前指针所指两条线构成的容器水量,然后根据两条线的高度,移动较短的线对应的指针,继续计算水量,直到两个指针相遇。

function maxArea(height: number[]): number {let left = 0;let right = height.length - 1;let maxWater = 0;while (left < right) {const width = right - left;const minHeight = Math.min(height[left], height[right]);const water = width * minHeight;maxWater = Math.max(maxWater, water);if (height[left] < height[right]) {left++;} else {right--;}}return maxWater;
}
复杂度分析
  • 时间复杂度:(O(n)),只需要遍历数组一次,n 是数组的长度。
  • 空间复杂度:(O(1)),只使用了常数级的额外空间来存储指针和最大水量。

方法三:优化双指针法(提前终止部分计算)

在双指针法的基础上,当移动指针时,如果新的指针所指的线高度小于等于之前的线高度,那么可以直接跳过,因为这样构成的容器水量不会更大。

function maxArea(height: number[]): number {let left = 0;let right = height.length - 1;let maxWater = 0;while (left < right) {const width = right - left;const minHeight = Math.min(height[left], height[right]);const water = width * minHeight;maxWater = Math.max(maxWater, water);if (height[left] < height[right]) {const currentLeftHeight = height[left];while (left < right && height[left] <= currentLeftHeight) {left++;}} else {const currentRightHeight = height[right];while (left < right && height[right] <= currentRightHeight) {right--;}}}return maxWater;
}
复杂度分析
  • 时间复杂度:\(O(n)\),虽然增加了一些内部的指针移动判断,但总体上仍然只需要遍历数组一次,n 是数组的长度。
  • 空间复杂度:\(O(1)\),只使用了常数级的额外空间来存储指针和最大水量。

你可以使用以下方式测试这些函数:

const height = [1, 8, 6, 2, 5, 4, 8, 3, 7];
console.log(maxArea(height));

综上所述,双指针法及其优化版本是解决该问题的高效方法,时间复杂度较低。

 


http://www.ppmy.cn/news/1580913.html

相关文章

电商项目Ts版本

文章目录 项目地址一、环境安装1.1 配置作为导入1.2 文件目录 二、路由2.1 publicRoutes 项目地址 教程作者&#xff1a;教程地址&#xff1a; 代码仓库地址&#xff1a; 所用到的框架和插件&#xff1a; dbt airflow一、环境安装 1.1 配置作为导入 vite.config.ts impor…

欢乐力扣:基本计算器

文章目录 1、题目描述2、思路代码括号 1、题目描述 基本计算器。  给你一个字符串表达式 s &#xff0c;请你实现一个基本计算器来计算并返回它的值。  注意:不允许使用任何将字符串作为数学表达式计算的内置函数&#xff0c;比如 eval() 。 2、思路 本人也不太会&#xff0c…

详解如何通过Python的BeautifulSoup爬虫+NLP标签提取+Dijkstra规划路径和KMeans聚类分析帮助用户规划旅行路线

系统模块&#xff1a; 数据采集模块&#xff08;爬虫&#xff09;&#xff1a;负责从目标网站抓取地点数据&#xff08;如名称、经纬度、描述等&#xff09; 数据预处理模块&#xff08;标签算法&#xff09;&#xff1a;对抓取到的地点数据进行清洗和分类。根据地点特征&…

C语言经典代码练习题

1.输入一个4位数&#xff1a;输出这个输的个位 十位 百位 千位 #include <stdio.h> int main(int argc, char const *argv[]) {int a;printf("输入一个&#xff14;位数&#xff1a;");scanf("%d",&a);printf("个位&#xff1a;%d\n"…

Linux 文件操作-标准IO函数3- fread读取、fwrite写入、 fprintf向文件写入格式化数据、fscanf逐行读取格式化数据的验证

目录 1. fread 从文件中读取数据 1.1 读取次数 每次读取字节数 < 原内容字节数 1.2 读取次数 每次读取字节数 > 原内容字节数 2.fwrite 向文件中写入数据 2.1写入字符串验证 2.2写入结构体验证 3. fprintf 将数据写入到指定文件 4. fscanf 从文件中逐行读取内容…

java数据结构之双端对列

一:定义 • 双端队列是一种具有队列和栈性质的数据结构&#xff0c;即可在线性表的两端进行插入和删除等操作 二:.Java API中的Deque 知道了双端队列的定义&#xff0c;下面我们来了解一下Java API中的Deque类&#xff0c;知道双端队列是如何创建以及使用的 增删查等方法摘要…

RAGFlow爬虫组件使用及ragflow vs dify 组件设计对比

上周末&#xff0c;两台电脑都失联了&#xff0c;一个是断网了&#xff0c;一个被我不小心关机。导致我两天没环境。只能整理&#xff0c;学点东西。 上周有个有个群友问我ragflow爬虫的没法使用的问题。幸好周六早上的时候实践了下。 使用网络爬虫 我搭建一个最简单的工作流…

Deepseek+飞书实现简历分析建议+面试题

步骤一&#xff1a;创建多维表格 点击云文档点击主页点击新建创建多维表格 步骤二&#xff1a;创建列 首先将多余的列进行删除 创建简历内容列&#xff0c;类型使用文本&#xff0c;目的是将简历内容复制进来 创建AI列&#xff1a;简历分析、简历建议、面试题 点击确定后&…