js算法题解(第四天)---LeetCode:11 盛最多水的容器

266 阅读2分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战

前言

每天至少一道算法题,死磕算法,今天我们再来一道题,来巩固一下数组算法的学习,我们要把学习重心放到解法的分析上,而不是做题的多少

题目

这是leetcode上的第11道题目11. 盛最多水的容器

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器。

难度:中等

图片.png

输入:[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)

总结

是不是对双指针法越来越熟练了,只要你一看这道题怎么感觉用双指针法可以,那么你就试试,就像做英语题多了,有了语感是一样的

讲解了几道数组类型的题目以后,接下来我们讲几道字符串类型的题目。因为他和数组真的很像呀,字符串底层不就是字符么,字符串和数组一样,也是线性的,存储空间是连续的,所以字符串的题目的解法和数组也很类似

参考:

11. 盛最多水的容器