用簡單思惟解決LeetCode中困難級別的題 —— 接雨水問題

目錄

以前看面試題的時候,看到了一個接雨水的問題,和小黃鴨討論以後,以爲頗有趣呢,這裏和你們分享一下這個解法。後來看到LeetCode上面有這道題,題號42,有興趣的能夠作一下。面試

問題描述

給定n個非負整數表示每一個寬度爲1的柱子的高度圖,計算彼此排列的柱子,下雨以後能接多少雨水。數組

示例1:markdown

輸入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
輸出:6優化

實例2:ui

輸入:height = [4,2,0,3,2,5]
輸出:9spa

你能不能先思考一下,遇到這種問題,你要怎麼作呢?3d

問題分析

首先咱們能夠根據給的數組,先畫出來柱子的長度。code

柱子長度.png

那麼咱們怎麼肯定接的雨水的量呢?固然是兩個都高中間低的地方,來存儲水,下面陰影的部分就是儲存水的位置。orm

雨水部分.png

那麼咱們須要對左邊和右邊最高水位作一個統計,這邊使用到了兩個輔助數組圖片

一個用來儲存左邊的最大接雨水數,一個存儲右邊的最大接雨水數。

最大接雨水數.png

選擇兩個中最小的那個做爲存儲水的量

QQ圖片20210421181221.png

固然還要減去本身柱子的高度。剩下的,就是能夠接的雨水了。

QQ圖片20210421181257.png

代碼整理

function trap(height) {
    if(!height.length) return 0;
    let left = []
    let right = []
    let lmax = rmax = 0
    let len = height.length
    let result = 0
    // 把左右最大出水量求出來
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        rmax = Math.max(height[len-i-1], rmax)
        left[i] = lmax
        right[len- i - 1] = rmax
    }
    // 算出最小的而後累加
    for(let i = 0; i < len; i++) {
        result += Math.min(left[i],right[i]) - height[i]
    }
    return result
};
複製代碼

若是想要寫法上優化一下,能夠第二次遍歷的時候可使用reduce

function trap(height) {
    if(!height.length) return 0;
    let left = []
    let right = []
    let lmax = rmax = 0
    let len = height.length
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        rmax = Math.max(height[len-i-1], rmax)
        left[i] = lmax
        right[len- i - 1] = rmax
    }
    return height.reduce((prev, item, index) => {
        return prev + Math.min(left[index],right[index]) - item
    }, 0)
};
複製代碼

分析

  • 時間複雜度O(n)
  • 空間複雜度O(n)

其實右邊數組的值的存儲是能夠省略的,雖然都是空間複雜度O(n),可是也算小小的優化點。

function trap(height) {
    if(!height.length) return 0;
    let left = []
    let lmax = rmax = 0
    let len = height.length
    let result = 0
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        left[i] = lmax
    }
    // 從後往前遍歷
    for(let i = len - 1; i >= 0; i--) {
        rmax = Math.max(height[i], rmax)
        result += Math.min(left[i],rmax) - height[i]
    }
    return result
};
複製代碼
相關文章
相關標籤/搜索