刷了道练习题目,关于蓄水池的问题,这里我分别用Python和Java实现一下。
题目:
Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
题目分析:
给出了指定高度的板子,由你随机组合,怎么实现装最多的水。
归纳水的容量计算公式为:
水的容量 = 板子距离 * 板子高度
板子距离:为两元素索引之间的差值;
板子高度:为两元素中较小值;
这里提供两种方法:
1.两个循环求最大的s值;
2.给数组两个指针,两指针同时向中间滑动,直到相遇,求这过程中的最大s值
用python 分别实现代码如下:
# -*- coding: utf-8 -*-
'''方法1:用两循环求最大s'''
## 指定若干指定长度的木板
l = [1,8,6,2,5,4,8,3,7]
max = 0
for i in range(len(l)):
for j in range(len(l)):
value1 = l[i]
value2 = l[j]
if value1 >= value2:
## 高度
h = value2
## 宽度
w = abs(i - j)
## 求面积,面积大的蓄水最多
s = h*w
if s > max:
max = s
print('最大值为:',max) ## 最大值为: 49
'''方法2:用左右双指针'''
## 左指针从0开始,又指针从len(l)-1开始
i = 0
j = len(l) - 1
while i < j:
## 求面积
s = min(l[i],l[j]) * (j -i)
if s > max:
max = s
## 左边指针对应的值小,则指针右移,指针寻找最大的值
if l[i] < l[j]:
i = i + 1
## 右边指针对应的值小,则指针左移,寻找最大的值
else:
j = j - 1
print('最大值为:',max) ## 最大值为: 49
用Java分别实现的代码如下:
//蓄水池问题的解法
//方法1:用两个循环解决
public class demo14 {
public static void main(String[] args) {
int[] ls = {1, 8, 6, 2, 5, 4, 8, 3, 7} ;
int l = ls.length;
int s;
int max = 0;
for (int i =0; i<l; i++) {
for (int j=0; j<l; j++) {
if (ls[i]>ls[j]) {
s = ls[j]*(i - j);
}
else {
s = ls[i] * (i - j);
}
if(s > max) {
max = s;
}
}
}
System.out.println("最大面积是:" + max);
}
}
import java.math.*;
//蓄水池问题的解法
//方法2:用左右两个指针去解决
public class demo15 {
public static void main(String[] args) {
int[] ls = {1, 8, 6, 2, 5, 4, 8, 3, 7} ;
int l = ls.length;
int s;
int max = 0;
int i = 0;
int j = l -1;
while(i<j) {
s = (j-i) * Math.min(ls[i], ls[j]);
//注意区分直接使用i++,j--的作用
if (ls[i] <ls[j]) {i++;}
else {j--;}
if (s>max) {
max = s;
}
}
System.out.println("最大值:" + max);
}
}
控制数组指针移动的时候,区分一下与直接使用i++,j--的区别就行。