寻寻觅觅
42.接雨水
题目描述
给定n个非负整数表示每个宽度为1的柱子的高度图 计算按照此排列的柱子,下雨之后能接多少雨水
示例
输入[4,2,0,3,2,5] 输出:9
循环
思路分析 将每一个柱形图 想象为一个桶 一个桶如果想知道能接多上水 就需要知道左右的木板
/**
*
* @param {number[]} nums
* 时间复杂度:O(n)
* 空间复杂度: O(n)
*/
function trap(nums){
let len = nums.length
let preMax = []
let ans = 0
preMax.push(nums[0])
for(let i = 1; i< len;i++){
preMax.push(Math.max( nums[i], preMax[i-1]))
}
let sufMax = []
sufMax[len-1] = (nums[len - 1])
for(let i = len - 2; i >= 0; i--){
sufMax[i] = Math.max(nums[i],sufMax[i+1])
}
for(let i = 0;i<len;i++){
ans += Math.min(preMax[i],sufMax[i]) - nums[i]
}
return ans
}
console.time('a')
let result = trap([4,2,0,3,2,5])
console.timeEnd('a') // 0.113ms
console.log('>>>',result) // 9
使用对撞指针
思路分析 一个桶可以装多少水 是由最短的木板决定的
请看code !!!
/**
*
* @param {number[]} nums
* 时间复杂度:O(n)
* 空间复杂度: O(1)
*/
function trap1(nums){
let len = nums.length
let l =0
let r = len - 1
let preMax = 0
let sufMax = 0
let ans = 0
while(r >= l){
preMax = Math.max(preMax,nums[l])
sufMax = Math.max(sufMax,nums[r])
// 1.前最大桶币 小于 后最大桶币 可以知道 l指针所指的桶可以装多少水
// 1.前最大桶币 大于 后最大桶币 可以知道 r指针所指的桶可以装多少水
if(preMax > sufMax){
ans += sufMax - nums[r]
r--
}else{
ans += preMax - nums[l]
l++
}
}
return ans
}
console.time('a')
let result1 = trap1([4,2,0,3,2,5])
console.timeEnd('a') // 0.057ms
console.log('>>>',result1) // 9
Baybay!!!