LeetCode練習:蓄水池問題 (內附Java和Python的實現方法)
阿新 • • 發佈:2018-11-17
刷了道練習題目,關於蓄水池的問題,這裡我分別用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
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--的區別就行。