演算法題目——蓄水池問題
阿新 • • 發佈:2018-12-10
題目: 給出了指定高度的任意兩個板子,每個木板位置間隔相等,由你隨機組合,怎麼實現裝最多的水。
分析:假設水池厚度相同,於是水容量計算公式:
水容量 = 板子距離*板子高度
板子距離:兩元素的索引之差
板子高度:兩元素的最小值
解題思路:
看到這道題目,首先可以肯定的是用窮舉法肯定能解決,這裡就不多介紹了,大家可以參考一下這篇文章
這裡我們採用的方法是:
1、 從最大寬度開始(即從陣列兩端開始,左記為L,右記為R),求出最大寬度下的面積,比較兩埠位置的值;
2、對值較小的一邊的埠索引值進行調整(左埠的話+1,右埠的話-1);
3、比較變化後的埠位置上的值是否大於調整前的值,是的話執行第4步,否則先判斷左埠是否仍小於右埠索引值,是的話再次執行第二步,否的話執行第4步;
4、計算此寬度下的最大面積,與最大面積比較,保留最大面積值,判斷左埠索引值是否仍小於右埠索引值,是的話再次執行第二步(縮小寬度),否的話跳出迴圈;
上面方法第三步主要是減少不必要的求面積操作,加快比較速度。
實現程式碼如下:
package com.liao.algorithm; import java.util.Random; public class WaterTank { public static void main(String[] args) { int len = 10; int max = 10; WaterTank wt = new WaterTank(); // 生成一個隨機陣列 int[] ns = wt.generateArray(len, max); wt.seekMaxArea(ns); } /* * 生成一個隨機陣列 陣列長度為n,陣列中最大值為max */ public int[] generateArray(int n, int max) { int[] ns = new int[n]; for (int i = 0; i < n; i++) { Random ran = new Random(); ns[i] = ran.nextInt(max) + 1; System.out.print(ns[i] + ","); } return ns; } /* * 尋找最大面積 從 陣列兩端開始 */ public void seekMaxArea(int[] ns) { int l = ns.length;// 陣列長度 int i = 0;// 陣列前端 int j = l - 1;// 陣列後端 int max = j * Math.min(ns[i], ns[j]);// 初始面積 int s, a;//中間變數 while (i < j) { if (ns[i] < ns[j]) { a = i; while (ns[a] >= ns[++i] && i < j) { //ns[a]不小於ns[++i]且i小於j,則i繼續加1,無需跳出迴圈求面積再做比較 continue; } } else { a = j; while (ns[a] >= ns[--j] && i < j) { //ns[a]不小於ns[--j]且i小於j,則j繼續減1,無需跳出迴圈求面積再做比較 continue; } } s = (j - i) * Math.min(ns[i], ns[j]);//求此時的面積 if (s > max) { max = s; } } System.out.println("最大蓄水量為" + max); } }