1、需求
很多程序員在面試的時候,都可能遇到一些邏輯思維/編程題,這樣的題目非常有意思。而且非常考驗程序員的解題技巧和代碼編寫能力。我這兒就曾經遇到過一個。
具體需求看圖
2、解題思路
廢話不多數。直接給大家講解思路:
1、先找出整個數組中的最大值。
2、整個數組就被這個最大值給分成了兩個數組。
3、左邊數組,從左往右遍歷,計算每個位置的蓄水數,計算規則是:找到當前位置的左邊蓄水的最大高度,當前位置的蓄水數就等於min(leftMaxHeight, maxHeight) - currentHeight
4、右邊數組,從右往左遍歷,計算每個位置的蓄水數,計算規則是:找到當前位置的右邊蓄水的最大高度,當前位置的蓄水數就等於min(rightMaxHeight, maxHeight) - currentHeight
5、最終把每個位置上的蓄水數加起來即可
3、實際代碼實現
package com.aura.funny.water;
/**
* 作者: 馬中華 https://blog.csdn.net/zhongqi2513
* 時間: 2019/6/20 10:33
* 描述:
* 求出一個一維數組的蓄水數。數組中的每個位置上的值,就是高度,
* 如果某個值的左右兩邊都有比它高的值,那麼這個位置就可以蓄水。
* 蓄水的容量 = max(左邊, 右邊) - 當前位置的值
*/
public class WaterArray01 {
public static void main(String[] args) {
// 能蓄水的位置和值: 0,1,2,0,0,2,2,0
int[] waterArray1 = new int[]{4,3,2,5,6,4,4,7};
int result1 = findTotalWaterStorage(waterArray1);
System.out.println("蓄水總量爲:" + result1);
// 能蓄水的位置和值: 0,0,0,3,4,1,4,0,1,2,0,0
int[] waterArray2 = new int[]{2,1,5,2,1,4,1,7,2,1,3,1};
int result2 = findTotalWaterStorage(waterArray2);
System.out.println("蓄水總量爲:" + result2);
// 能蓄水的位置和值: 0,0,0,3,4,1,4,0,1,2,0,0
int[] waterArray3 = new int[]{4,1,3,5,3,6,2,1,4,7,2,6,4};
int result3 = findTotalWaterStorage(waterArray3);
System.out.println("蓄水總量爲:" + result3);
}
/**
* 整體思路:
* 先找到最高點,然後分別從左,和 從右 往這個高點遍歷。算出蓄水數
*/
private static int findTotalWaterStorage(int[] waterArray) {
int totalWater = 0;
// 最高點的值
int maxHeight = waterArray[0];
// 最高點的位置
int maxHeightIndex = 0;
// 找出最高點的位置和值
for(int i = 1; i<waterArray.length; i++){
if(maxHeight < waterArray[i]){
maxHeight = waterArray[i];
maxHeightIndex = i;
}
}
/**
* 隱性前提: leftHeight 一定小於或者等於 maxHeight
* 隱性前提: rightHeight 一定小於或者等於 maxHeight
*/
// 從左往右掃描
int leftHeight = waterArray[0];
for(int i=1; i<maxHeightIndex; i++){
// 如果當前遍歷的位置是低谷
if(waterArray[i] < leftHeight){
totalWater += (leftHeight - waterArray[i]);
}else{
// 如果不是低谷,則更換左邊的較高位置
leftHeight = waterArray[i];
}
}
// 從右往左
int rightHeight = waterArray[waterArray.length-1];
for(int i=waterArray.length-2; i>maxHeightIndex; i--){
// 如果當前遍歷的位置是低谷
if(waterArray[i] < rightHeight){
totalWater += (rightHeight - waterArray[i]);
}else{
// 如果不是低谷,則更換左邊的較高位置
rightHeight = waterArray[i];
}
}
return totalWater;
}
}
這種思路的求解的時間複雜度是:O(N)級別。網上其他的O(N * LogN)級別都不可取
4、執行效果
大功告成。!!!!