打怪升级第5天

75 阅读1分钟

寻寻觅觅

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!!!