解題思路
要計算所有臺階上的積水,只要將每個臺階上的積水量累加,就是所有臺階的積水量。而每個臺階的若想積水則其左右臺階的(最高)高度都要高於當前臺階纔可以。
如題,當前臺階爲:
0,1,0,2,1,0,1,3,2,1,2,1
每個臺階的積水量爲:
0,0,1,0,1,2,1,0,0,1,0,0
每個臺階左邊最高臺階高度:(不存在則置0)
0,0,1,1,2,2,2,2,3,3,3,3
每個臺階右邊最高臺階高度:(不存在則置0)
3,3,3,3,3,3,3,2,2,2,2,0
可見,當前臺階的積水量由其左右最高臺階高度決定,噹噹前臺階高度大於任一左右最高臺階時,當前臺階積水爲:0,否則當前臺階積水量 = 其左右最高臺階中的次高臺階 - 當前臺階高度
如圖:
代碼實現:
<?php
//$steps = [0,1,0,2,5,0,1,3,2,4,0,2,0,1]; //測試數據
$steps = [0,1,0,2,1,0,1,3,2,1,2,1];
$leftTopStep = get_left_top_steps($steps); //數組中每個臺階左邊最高臺階高度,
//將字符串翻轉,計算左邊最高臺階後,再翻轉一次則爲右邊最高臺階
$rightTopStep = get_left_top_steps(array_reverse($steps));
$rightTopStep = array_reverse($rightTopStep);//數組中每個臺階右邊最高臺階高度,
//計算所有臺階積水量
$sum = 0;
foreach ($steps as $k => $high){
$weater = 0;
if($steps[$k] < $leftTopStep[$k] && $steps[$k] < $rightTopStep[$k]){
$weater = $leftTopStep[$k] - $steps[$k];
if($weater > ($rightTopStep[$k] - $steps[$k])){
$weater = $rightTopStep[$k] - $steps[$k];
}
$sum += $weater;
}
$weaterStep[$k] = $weater; //記錄每個臺階積水量,可忽略
}
echo '所有臺階積水量爲:'.$sum.'<br>';
//以下爲測試輸出
echo "臺階高度:<br>";
foreach ($steps as $k => $v){
echo $v."__";
}
echo "<br>";
echo "左邊臺階最高高度:<br>";
foreach ($leftTopStep as $k => $v){
echo $v."__";
}
echo "<br>";
echo "右邊臺階最高高度:<br>";
foreach ($rightTopStep as $k => $v){
echo $v."__";
}
echo "<br>";
echo "每個臺階積水量:<br>";
foreach ($weaterStep as $k => $v){
echo $v."__";
}
echo "<br>";
/**
* 計算數組中每個臺階左邊最高臺階高度,不存在則置0
* @param $steps
* @return array
*/
function get_left_top_steps($steps){
$leftTopStep = [];
$count = count($steps);
for($i = 0 ; $i < $count ; $i++){
if(!isset($steps[$i-1])){
$leftTopStep[$i] = 0;
}else{
if($steps[$i-1] > $leftTopStep[$i-1]){
$leftTopStep[$i] = $steps[$i-1];
}else{
$leftTopStep[$i] = $leftTopStep[$i-1];
}
}
}
return $leftTopStep;
}
輸出
所有臺階積水量爲:6
臺階高度:
0__1__0__2__1__0__1__3__2__1__2__1__
左邊臺階最高高度:
0__0__1__1__2__2__2__2__3__3__3__3__
右邊臺階最高高度:
3__3__3__3__3__3__3__2__2__2__1__0__
每個臺階積水量:
0__0__1__0__1__2__1__0__0__1__0__0__