• leetcode_day03


    https://leetcode-cn.com/problems/container-with-most-water/

    题目:盛水最多的容器

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

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

    思路:循环遍历,容器的宽,永远是容器两端中,比较矮的那一端

    长度:两端距离

    把所有可能性,都算一边,然后比较,找到最大的,即可。

     1 class Solution:
     2     def maxArea(self, a):
     3         max_area = min(a[0], a[1])
     4         for i in range(0, len(a)):
     5             for j in range(i+1, len(a)):
     6                     area = min(a[i], a[j]) * (j - i)
     7                     if area > max_area:
     8                         max_area = area
     9         return max_area
    10         

    存在问题:暴力解法,耗时太长。。。

    更新:

    看了官方答案之后。从两侧开始移动更好。

    盛水面积公式:

    h = J - I

    Area = min(a[I], a[J]) * h

    只要,两端向内部移动,则长度h一定变小

    而我们的目的是:要让面积Area变大!!!

    所以,就一定要使min(a(i),a(j))变大

       ——所以,制约问题的核心,就是两端较小的那一侧

       ——所以,我们的目的就是,要让两端较小的那一侧变大!

       ——所以,只需要移动较小的那一端就可以。

    A:

      

     (1)假设移动值较大的一侧(i):

      a:a[i]变小,跑到了1处,变得比较小侧a[j]还小,则min(a[i], a[j])变小,h变小,area变小。

      b:  a[i]变大,跑到了3处,min(a[i], a[j]) 保持不变,还为a[j](因为此时a[j]没有移动),h变小,area变小。

    (2)假设移动值较小的一侧(j):

      a:a[j]变小,跑到了2处,变得比原来更小,则min(a[i], a[j])变小,h变小,area变小。

      b:a[j]变大,跑到了4处,变大比原来大,甚至比原来较大一侧更大,则min(a[i], a[j])变大,h变小,area有可能变大

      c:a[j]变大,跑到了5处,变大比原来大,但是不如原来较大一侧更大,则min(a[i], a[j])变大,h变小,area有可能变大

    综上所述:Area变大的情况只有:让原来两端较小的一侧变大。

     ——所以只需要移动值较小的一端,并且让其变大(如果较小的一端移动之后,值还变小了,则无需计算Area值,继续移动)。

    还有一个问题:i向右移动,j向左移动,最终,二者可能翻转过来,i跑到j的右侧,j在i的左侧,此时,就又和之前的情况发生重复。

    解决方法:while i < j:——只计算让i小于j

    代码:

     1 class Solution:
     2     def maxArea(self, a):
     3         i = 0
     4         j = len(a)-1
     5         max_area = min(a[i], a[j]) * (j-i)
     6         while i < j:
     7             if a[i] < a[j]:
     8                 old = a[i]
     9                 i += 1
    10                 if a[i] < old:
    11                     continue
    12             else:
    13                 old = a[j]
    14                 j -= 1
    15                 if a[j] < old:
    16                     continue
    17             area = min(a[i], a[j]) * (j-i)
    18             if max_area < area:
    19                 max_area = area
    20         return max_area

        

  • 相关阅读:
    「SAP技术」SAP MM MB5M报表不显示特殊库存数据
    python-day3-条件判断与循环
    python-day2-运算符
    Mysql数据库意外崩溃导致表数据文件损坏无法启动的问题解决
    图书管理系统(Servlet+Jsp+Java+Mysql,附下载演示地址)
    求解最长递增子序列(LIS) | 动态规划(DP)+ 二分法
    HTML+CSS+JavaScript实现植物大战僵尸(附演示地址)
    面试官:如何在Integer类型的ArrayList中同时添加String、Character、Boolean等类型的数据? | Java反射高级应用
    面试官:手撕十大排序算法,你会几种?
    用x种方式求第n项斐波那契数,99%的人只会第一种
  • 原文地址:https://www.cnblogs.com/tommyngx/p/10467763.html
Copyright © 2020-2023  润新知