Leedcode—盛最多水的容器

给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (iai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (iai) 和 (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

class Solution{
    
    public int maxArea(int[] height) {
        int i = 0;
        int j = height.length - 1;
        int max = 0;
        while(i < j) {
            int area = (j - i) * Math.min(height[i], height[j]);
            if(area > max)
                max = area;
            if(height[i] <= height[j])
                ++i;
            else if(height[j] < height[i])
                --j;
            else
                break;
        }
        return max;
        
    }
}

 

 

变形:容器储水问题

 

给定一个大小为n的水池组,求水池最多能蓄水多少

例:第一行输入n=5

       第二行输入n个值[5,2,1,4,3]

输出:5


思路分析:

(1)很容易先想到暴力求解:

        a.遍历数组的每个位置,分别依次求出当前位置左侧的最大值和右侧的最大值

        b.当前位置,容器能够储存的水量为Math.max( 0, Math.min(left,right)-arr[i] ),也就是当前位置的左右侧的最小值减去当前位             置的储水量。

        c.最后遍历每个位置,求出每个位置的储水量,相加即为总储水量。   

           时间复杂度O(N^2)

(2)但由于暴力解决时间复杂度过高,故在此采用指针的方式,来更新左右最大值。节省时间和空间。

package com.cn.java.niuke;

import java.util.Scanner;
/*
 * 水池储水问题
 * 输入:5 2 1 4 3
 * 输出:5*/
public class test{
	public static void main(String[] args) {
		//数组大小n
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		//定义水池
		int[] pool = new int[n];
		for(int i = 0;i<pool.length;i++) {
			pool[i]=in.nextInt();
		}
		
		System.out.println(findValue(pool));
	}
	
	
	private static int findValue(int[] pool) {
		
		if(pool==null || pool.length<3) {
			return 0;
		}
		int leftmax=pool[0];//找到左边最大的一个
		int rightmax=pool[pool.length-1];//找到右边最大的一个
		int value=0;//总容量
		int l=1;//左指针
		int r=pool.length-2;//右指针
		
		while(l<=r) {
			if(leftmax <rightmax) {
				value += Math.max(leftmax-pool[l], 0);
				leftmax = Math.max(leftmax, pool[l++]);
			}else {
				value += Math.max(rightmax-pool[r], 0);
				rightmax = Math.max(rightmax, pool[r--]);
			}
		}
		return value;
	}
}

结果:

5
5 2 1 4 3
5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值