zoukankan      html  css  js  c++  java
  • LeetCode 11. 盛最多水的容器

    题目:


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

    说明:你不能倾斜容器,且 n 的值至少为 2。

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

    输入:[1,8,6,2,5,4,8,3,7]
    输出:49
    

    思路

    把容器作为一个长方形,我们都知道长方形的面积等于长x宽,这里

    长 = j-i(j,i为index)

    宽 = [n1,n2,n3...]

    所以面积最大为=max{[j-i] * n}

    方法一:

    依次按index比较,取所有情况的最大值,但是时间超时,虽然想法笨了点,但是方案是可行的,也是一种思路。

    class Solution(object):
        def maxArea(self, height):
            """
            :type height: List[int]
            :rtype: int
            """
            length = len(height)
            res = 0
            for i in range(length):
                for m in range(length):
                    if  m >i: #shift m,i只与比其大的数取比较
                        if height[i] <=height[m]:  #正序,取i作为宽,index之差为长
                            res = max(res,(m-i)*height[i])
                        elif height[i]>=height[m]: #逆序,取m作为宽,index之差为长
                            res = max(res,(m-i)*height[m])
            return res
     	#或者用while循环
    	for i in range(length):
                  n = length -1
                  while (n>i):
                         if height[i]<=height[n]:
                              res = max(res,(n-i)*height[i])
                          elif height[i]>=height[n]:
                              res = max(res,(n-i)*height[n])
                              n = n-1
            return res
    

    方法二:

    方法一中,2个循环累积遍历的时间太长,要想办法减少该循环,所以得换个思路。可是 想了一下,不管怎么样,都需要找长度和高度最大的情况,但是我并不知道他们的乘积谁最大,所以还是得去循环去找,然后循环比较,这样看,和方法一的思路是一样的,应该还是超时。所以只好参考评论题解寻找最优解。

    本题是一道经典的面试题,最优的做法是使用「双指针」。如果读者第一次看到这题,不一定能想出双指针的做法

    默念三遍,我是猪,我是猪,我是猪。就算没有想到双指针,我也应该要去想怎么去减少循环次数,也就是最大有效面积,说不准能想到移动右边距的情况,可是思维还是僵在之前的点子上了,不服不行呀,解题思路都是培养出来的,没错,继续加油。

    先解释一下为什么可以用左右双指针移动来计算(摘自评论的一句总结)。

    --->矮柱子选取后如果移动高柱子的话面积是一定会减小的,因为长度距离在变小的时候,此时高度只能小于或等于矮的柱子。因此只能移动矮的柱子这边才有可能使得高度比矮柱子大

    其实仔细思考一下,不难发现这个结论。但是我是猪,哈哈哈。

    class Solution(object):
        def maxArea(self, height):
            """
            :type height: List[int]
            :rtype: int
            """
            length = len(height)
            n = length-1
            res = 0
            i = 0
            while (n>i):
                if height[i] <=height[n]:
                    res = max(res,(n-i)*height[i])
                    if i+1 < length:
                        i +=1
                elif height[i] >height[n]:
                    res = max(res,(n-i)*height[n])
                    if n >= 1:
                        n -=1
            return res
    

    执行用时 :44 ms, 在所有 Python 提交中击败了47.89%的用户

    内存消耗 :13.5 MB, 在所有 Python 提交中击败了8.33%的用户

  • 相关阅读:
    C++为什么不可以把一个数组直接赋值给另一个数组
    Eigen 矩阵库学习笔记
    HTTP请求报文和HTTP响应报文
    剔除三个(包括三个以上)的子串
    c语言实现:4和7幸运数字的题
    oracle顺序控制语句goto、null和分页过程中输入输出存储、java程序的调用过程
    oracle的控制语句if和循环语句loop while for
    oracle函数、包、变量的定义和使用、重点”结构体和数组”
    oracle pl/sql简介、块、过程
    oracle角色
  • 原文地址:https://www.cnblogs.com/xiaoqiangink/p/12970964.html
Copyright © 2011-2022 走看看