zoukankan      html  css  js  c++  java
  • 42. Trapping Rain Water

    ▶ 一个有趣的算法题。给定一个非负数数组,把数组中各元素看做是宽度为 1,高度为其值的砖块,求这些砖块最大能盛多少水。如给定数组 [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1],则水量为 6。参考原题答案 https://leetcode.com/problems/trapping-rain-water/solution/

      

    ● 代码,598ms 。暴力枚举,对于每个格子,搜索其左右两侧最高的高度,两高度中的较小者与该格子自身高度的差即为该格子盛水量。

     1 class Solution
     2 {
     3 public:
     4     int trap(vector<int>& height)
     5     {
     6         const int size = height.size();
     7         int ans, i, j, max_l, max_r; 
     8         for (ans = 0, i = 1; i < size - 1; i++)
     9         {
    10             max_l = max_r = 0;
    11             for (j = i; j >= 0; max_l = max(max_l, height[j--])); 
    12             for (j = i; j < size; max_r = max(max_r, height[j++]));
    13             ans += min(max_l, max_r) - height[i];
    14         }
    15         return ans;
    16     }
    17 };

    ● 代码,12 ms,动态规划。从原数组中得到一个单调不减序列和一个单调不增序列,两序列的交集即为装水量。

      

     1 class Solution
     2 {
     3 public:
     4     int trap(vector<int>& height)
     5     {
     6         if (height.size() == 0)
     7             return 0;
     8         const int size = height.size();
     9         vector<int> left_max(size), right_max(size);
    10         int ans, i;
    11         for (ans = 0, left_max[0] = height[0], i = 1; i < size; i++)
    12             left_max[i] = max(height[i], left_max[i - 1]);
    13         for (right_max[size - 1] = height[size - 1], i = size - 2; i >= 0; i--)
    14             right_max[i] = max(height[i], right_max[i + 1]);
    15         for (i = 1; i < size - 1; i++)
    16             ans += min(left_max[i], right_max[i]) - height[i];
    17         return ans;
    18     }
    19 };

    ● 代码,13 ms,神奇的双指针法。简单的说明:lp 从左向右扫描,并且不断记录目前为止最高坎的高度,当遇到高度降低时发生积水,向 ans 添加本格的积水量(本格积水量等于最高高度减去当前高度);rp 从右向左扫描,工作方式类似。注意每次搜索下一格之前要先对 candidatex[ lp ] 和 candidatex[ rp ] 做一个比较,只在较低者那边进行上述维护和加值操作,这是为了使最后 lp 和 rp 相遇时汇合于整个数组的最高高度处,此时以该最高高度为分水岭,其左右两边的积水都已经算完,可以返回答案。

     1 class Solution
     2 {
     3 public:
     4     int trap(vector<int>& height)
     5     {
     6         int lp, rp, ans, lpmax, rpmax;
     7         for (ans = lpmax = rpmax = lp = 0, rp = height.size() - 1; lp < rp;)
     8         {
     9             if (height[lp] < height[rp])
    10             {
    11                 height[lp] >= lpmax ? (lpmax = height[lp]) : (ans += lpmax - height[lp]);
    12                 lp++;
    13             }
    14             else 
    15             {
    16                 height[rp] >= rpmax ? (rpmax = height[rp]) : (ans += rpmax - height[rp]);
    17                 rp--;
    18             }
    19         }
    20         return ans;
    21     }
    22 };
  • 相关阅读:
    css 弹出框
    net stop 出现1060错误
    a href=#与 a href=javascript:void(0) 的区别
    ubuntu如何安装Mac主题
    js arguments.callee & caller的用法及区别
    js函数——setinterval和setTimeout
    highcharts简介
    highcharts柱状图和饼图的数据填充
    jqgrid的外观重绘
    laravel定时任务
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/8322449.html
Copyright © 2011-2022 走看看