1. 程式人生 > 其它 >【每日一題】【動態規劃】【雙指標】2021年11月30日-42. 接雨水

【每日一題】【動態規劃】【雙指標】2021年11月30日-42. 接雨水

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

四種解法:常規方法、動態規劃、雙指標一次優化

還有其他:單調棧方法

//傳統做法
class Solution {
    public int trap(int[] height) {
        int res = 0;
        int size = height.length;
        for(int i = 1; i < size - 1; i++) {
            int leftMax = 0, rightMax = 0;
            for
(int j = i; j >= 0; j --) { leftMax = Math.max(leftMax, height[j]); } for(int j = i; j < size; j++) { rightMax = Math.max(rightMax, height[j]); } res += Math.min(leftMax, rightMax) - height[i]; } return
res; } } //動態規劃 //注意動態規劃遞推式的左邊下標都是i class Solution { public int trap(int[] height) { int n = height.length; int res = 0; int[] leftMax = new int[n]; leftMax[0] = height[0]; for(int i = 1; i < n; i++) { leftMax[i] = Math.max(leftMax[i - 1], height[i]); }
int[] rightMax = new int[n]; rightMax[n - 1] = height[n - 1]; for(int i = n - 2; i >= 0; i--) { rightMax[i] = Math.max(rightMax[i + 1], height[i]); } for(int i = 0; i < n; i++) { res += Math.min(leftMax[i], rightMax[i]) - height[i]; } return res; } } //雙指標 class Solution { public int trap(int[] height) { int res = 0; int left = 0, right = height.length - 1; int leftMax = 0, rightMax = 0; while(left < right) { leftMax = Math.max(leftMax, height[left]); rightMax = Math.max(rightMax, height[right]); if(leftMax < rightMax) { //最小值-當前值後再變左右(變小的一方) res += leftMax - height[left]; left++; } else { res += rightMax - height[right]; right--; } } return res; } }

本文來自部落格園,作者:劉金輝,轉載請註明原文連結:https://www.cnblogs.com/liujinhui/p/15626289.html