「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」
前言
每天至少一道算法题,死磕算法,今天我们再来一道题,来巩固一下数组算法的学习,我们要把学习重心放到解法的分析上,而不是做题的多少
题目
这是leetcode上的第11道题目11. 盛最多水的容器
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
难度:中等
输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
思路
第一步:从题目中提取关键信息
- 1.容器不能倾斜(放心吧,倾斜我都不知道怎么玩)
- 2.找出两条线,使得他们与x轴共同构成的容器可以容纳更多的水
第二步:联想
我们小时候做数学题曾经遇到过一个非常经典的题目:"木桶原理",一个木桶可以装入多少水取决于最短的那块板;和咱们这道题很像呀。
那我们这道题计算面积的公式也就可以得出来:两条线中短的那条线*两条线的距离
以前我们说过,遇到数组问题,你就往双指针上套,这道题同样适用
- 分为左右指针,分别指向第一条和最后一条线,while(left<right)进行循环
- 如果左侧的线小于右侧的线,那么面积为:
左侧的线*两条线的距离,左侧的线右移,找更高的线 - 如果右侧的线小于等于左侧的线,那么面积为:
右侧的线*两条线的距离,右侧的线左移动,找更高的线
解题
经过上面的一堆分析,解题步骤也就很好写了
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function (height) {
// height是线高度数组
// 定义两个指针
let left = 0;
let right = height.length - 1;
// 定义结果
let res = 0;
while (left < right) {
// 定义每次获取到的面积
let result;
if (height[left] < height[right]) {
// 如果左侧的线小于右侧的线,那么面积为:左侧的线*两条线的距离,左侧的线右移,找更高的线
result=height[left] * (right - left);
left++;
} else {
// 如果右侧的线小于等于左侧的线,那么面积为:右侧的线*两条线的距离,右侧的线左移动,找更高的线
result=height[right] * (right - left);
right--;
}
res=res>result?res:result;
}
return res;
};
- 时间复杂度:O(n),双指针时间复杂度为O(n)
- 空间复杂度:O(1)
总结
是不是对双指针法越来越熟练了,只要你一看这道题怎么感觉用双指针法可以,那么你就试试,就像做英语题多了,有了语感是一样的
讲解了几道数组类型的题目以后,接下来我们讲几道字符串类型的题目。因为他和数组真的很像呀,字符串底层不就是字符么,字符串和数组一样,也是线性的,存储空间是连续的,所以字符串的题目的解法和数组也很类似