1. 程式人生 > >LeetCode練習:蓄水池問題 (內附Java和Python的實現方法)

LeetCode練習:蓄水池問題 (內附Java和Python的實現方法)

 

    刷了道練習題目,關於蓄水池的問題,這裡我分別用Python和Java實現一下。

題目:

Given n non-negative integers a1a2, ..., an , where each represents a point at coordinate (iai). 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.

LeetCode演算法 每日一題 11:蓄水池問題

 

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--的區別就行。