Algorithm 找到最大可能的面积

Algorithm 找到最大可能的面积,algorithm,area,Algorithm,Area,给定n个非负整数a1,a2,…,an,其中每个表示a 坐标(i,ai)处的点。n绘制垂直线,以便 线i的两个端点位于(i,ai)和(i,0)。找两行,, 它与x轴一起构成一个容器 含水量最多 注意:容器不能倾斜 一个解决方案是,我们把每一条线都取下来,找出每一条线的面积。这需要O(n^2)。没有时间效率 另一种解决方案是使用DP找到每个索引的最大面积,然后在索引n处,我们将得到最大面积。 我想是O(n) 还有更好的解决方案吗?这个问题是一个更简单的问题。给定的情况可以看作是一个二进制矩阵。考虑矩

给定n个非负整数a1,a2,…,an,其中每个表示a 坐标(i,ai)处的点。n绘制垂直线,以便 线i的两个端点位于(i,ai)和(i,0)。找两行,, 它与x轴一起构成一个容器 含水量最多

注意:容器不能倾斜

一个解决方案是,我们把每一条线都取下来,找出每一条线的面积。这需要O(n^2)。没有时间效率

另一种解决方案是使用DP找到每个索引的最大面积,然后在索引n处,我们将得到最大面积。 我想是O(n)


还有更好的解决方案吗?

这个问题是一个更简单的问题。给定的情况可以看作是一个二进制矩阵。考虑矩阵的行作为X轴和列为Y轴。对于数组中的每个元素a[i],设置

Matrix[i][0] = Matrix[i][1] = ..... = Matrix[i][a[i]] = 1
例如,对于
a[]={5,3,7,1}
,我们的二进制矩阵由下式给出:

1111100
1110000
1111111
1000000

这里的许多人把这个问题误认为是最大矩形问题,事实并非如此

解决方案

  • 删除所有元素aj,使ai>=aj=j找到最大值am
  • 设as=a1
  • 对于j=2到m-1,如果as>=aj,则删除aj,否则as=aj
  • 让as=an
  • 对于j=n-1到m+1,如果as>=aj,则删除aj,否则as=aj
  • 请注意,结果值看起来像一个金字塔,也就是说,最大值左侧的所有元素严格递增,右侧的所有元素严格递减
  • i=1,j=n。m是最大值的位置
  • 当我=m
  • 找到ai和aj之间的区域并跟踪最大值
  • 如果ai

  • 复杂性是线性的(O(n))

    这个问题可以在线性时间内解决

  • 按照从高到低的顺序,构建可能的左墙列表(位置+高度对)。这是通过获取最左边的墙并将其添加到列表中,然后从左到右遍历所有可能的墙,并获取比添加到列表中的最后一面墙大的每面墙来完成的。例如,对于数组

    2 5 4 7 3 6 2 1 3
    
    您可能的左墙为(成对为(pos,val)):

  • 以相同的方式构建可能的右墙列表,但从右向左。对于上述阵列,可能的右墙为:

    (3, 7) (5, 6) (8, 3)
    
  • 从尽可能高的水位开始,这是两个列表前面的墙的最小高度。使用这些墙计算水的总体积(可能是负数或零,但这是可以的),然后通过从列表中弹出一个元素来降低水位,使水位下降最少。计算每个高度处的可能水量,并取最大值

  • 在这些列表上运行此算法如下所示:

    L: (3, 7) (1, 5) (0, 2)  # if we pop this one then our water level drops to 5
    R: (3, 7) (5, 6) (8, 3)  # so we pop this one since it will only drop to 6
    Height = 7
    Volume = (3 - 3) * 7 = 0
    Max = 0
    
    L: (3, 7) (1, 5) (0, 2)  # we pop this one now so our water level drops to 5
    R: (5, 6) (8, 3)         # instead of 3, like if we popped this one
    Height = 6
    Volume = (5 - 3) * 6 = 12
    Max = 12
    
    L: (1, 5) (0, 2)
    R: (5, 6) (8, 3)
    Height = 5
    Volume = (5 - 1) * 5 = 20
    Max = 20
    
    
    L: (1, 5) (0, 2)
    R: (8, 3)
    Height = 3
    Volume = (8 - 1) * 3 = 21
    Max = 21
    
    L: (0, 2)
    R: (8, 3)
    Height = 2
    Volume = (8 - 0) * 2 = 16
    Max = 21
    
    步骤1、2和3都在线性时间内运行,因此完整的解决方案也需要线性时间

    int maxArea(向量和高度){
    
    int maxArea(vector<int> &height) {
        int ret = 0;
        int left = 0, right = height.size() - 1;
        while (left < right) {
            ret = max(ret, (right - left) * min(height[left], height[right]));
            if (height[left] <= height[right])
                left++;
            else
                right--;
        }
        return ret;
    }
    
    int-ret=0; int left=0,right=height.size()-1; while(左<右){ ret=最大值(ret,(右-左)*最小值(高度[左]、高度[右]);
    如果(高度[左],这里有一个Java实现:

    基本思想是使用前后两个指针,计算沿途的面积

    public int maxArea(int[] height) {
        int i = 0, j = height.length-1;
        int max = Integer.MIN_VALUE;
    
        while(i < j){
            int area = (j-i) * Math.min(height[i], height[j]);
            max = Math.max(max, area);
            if(height[i] < height[j]){
                i++;
            }else{
                j--;
            }
        }
    
        return max;
    }
    
    public int maxArea(int[]高度){
    int i=0,j=height.length-1;
    int max=整数的最小值;
    而(i
    是,但是他们没有提供解释

    我已经找到了一个非常清楚的解释。简而言之,它是这样的:

    给定长度为n的数组高度:

  • 从尽可能宽的容器开始,即从0处的左侧到n-1处的右侧

  • 如果存在更好的容器,它将更窄,因此其两侧必须高于当前选择的较低一侧

  • 因此,如果height[left]
  • 计算新的面积,如果它比你目前拥有的要好,就替换它

  • 如果左<右,则从2开始

  • 我的C++实现:

    int maxArea(向量和高度){
    自动电流=配对(0,height.size()-1);
    自动最佳面积=面积(高度,当前);
    while(current.first
    这是一个干净的Python3解决方案。此解决方案的运行时间为O(n)。请记住,两条线之间形成的区域由较短的线的高度和线之间的距离决定

    def maxArea(height):
        """
        :type height: List[int]
        :rtype: int
        """
        left = 0
        right = len(height) - 1
        max_area = 0
        while (left < right):
            temp_area = ((right - left) * min(height[left], height[right]))
            if (temp_area > max_area):
                max_area = temp_area
            elif (height[right] > height[left]):
                left = left + 1
            else:
                right = right - 1
        return max_area
    
    def最大面积(高度):
    """
    :类型高度:列表[int]
    :rtype:int
    """
    左=0
    右=透镜(高度)-1
    最大面积=0
    而(左<右):
    温度面积=((右-左)*最小值(高度[左]、高度[右])
    如果(温度面积>最大面积):
    最大面积=温度面积
    elif(高度[右]>高度[左]:
    左=左+1
    其他:
    右=右-1
    返回最大面积
    
    你能详细说明你在想什么吗?因为我和AI没有关系,我想你必须考虑所有的组合,因为两点我
    def maxArea(height):
        """
        :type height: List[int]
        :rtype: int
        """
        left = 0
        right = len(height) - 1
        max_area = 0
        while (left < right):
            temp_area = ((right - left) * min(height[left], height[right]))
            if (temp_area > max_area):
                max_area = temp_area
            elif (height[right] > height[left]):
                left = left + 1
            else:
                right = right - 1
        return max_area