有意思的数学题:Trapping Rain Water

2023-10-13 22:10

本文主要是介绍有意思的数学题:Trapping Rain Water,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LeetCode传送门 https://leetcode.com/problems/trapping-rain-water/

 

 

目标:找出积木能容纳的水的“面积”,如图中黑色部分是积木,蓝色为可容纳水的部分

假设:积木宽度均为1

输入:各个积木的高度

输出:所有积木能容纳水的“面积”

 

思考过程

1. 逐一求积木的间隔似乎不太容易。特别对于图中3-7积木间的容积,如果可以先求底部(4-6间)的容积,当求解上层(3-7)的容积时,还需要做额外的处理,如减掉底部的高度。

2. 既然如此,可否先求出3-7间整体的容积,再将两积木之间的积木面积(4、5、6)减去,即可得这个区域的容积?

3. 那么问题转换成了,已知一个积木,如何寻找下一个积木,并计算这个两积木间的容积

4. 尝试一,寻找一个至少不比当前积木低的积木,作为下一个积木,如图例子为当前积木3,下一个积木7。那么之间的容积如何计算呢,简单,积木3的高度乘以两积木间的间隔宽度,再减去,积木3与积木7之间的积木(4、5、6)面积。

5. 问题:下次迭代从何开始?上一个例子,可以从积木7继续算起。然而如果找不到相应的积木呢,那么从积木3的下一个积木4开始。

6. 看起来,似乎正确。于是乎,开始写代码了。然而第一次提交就献给了WA(/(ㄒoㄒ)/~~)

7. 错误的情况,如果当前的积木是一个特别高的积木,后继找不到更高的积木,然而实际上之间是可能有容积的!不赘述了,补救思路是:在寻找更高的积木的同时,记录当前找到的最高的积木。如果没有找到更高的积木,使用当前找到的最高的积木作为下一个积木,并计算容积。

 

思路总结

迭代的过程

1. 寻找下一个至少不比当前积木低的积木,寻找的同时,记录当前找到的最高的积木高度

2. 如果找到,则计算两积木之间的容积(计算过程见思考过程2)

3. 如果没有找到,则计算当前积木与当前找到的最高的积木之间的容积

4. 当前积木设置为找到的积木(可能是2或3的情况),继续迭代

 

时间复杂度

O(n)

 

代码实现

 1 #include <iostream>
 2 #include <vector>
 3 
 4 using namespace std;
 5 
 6 class Solution {
 7 public:
 8     int trap(vector<int>& height) {
 9         if (height.size() == 0) {
10             return 0;
11         }
12 
13         int water = 0;
14         int preIndex = 0;
15         int preHeight = 0;
16 
17         // 找到第一个高度非0的bar
18         while (preIndex < height.size() - 1 && height[preIndex] == 0) {
19             ++preIndex;
20         }
21 
22         if (preIndex == height.size() - 1) {
23             return 0;
24         }
25 
26         // 遍历
27         while (preIndex < height.size()) {
28             preHeight = height[preIndex];
29 
30             // 寻找更高的或相等的bar
31             // 同时记录遍历过的最高的bar
32             // 如果寻找不到更高的或相等的bar时,使用记录值计算
33             int next = preIndex + 1;
34             int minHeight = 0;
35             int minIndex = next;
36 
37             while (next < height.size() && height[next] < preHeight) {
38                 if (height[next] > minHeight) {
39                     minHeight = height[next];
40                     minIndex = next;
41                 }
42                 ++next;
43             }
44 
45             // 如果找到
46             if (next != height.size()) {
47                 water += (preHeight * (next - preIndex - 1)); // 计算总面积
48 
49                 for (int i = preIndex + 1; i < next; ++i) { // 减去中间bar面积
50                     water -= height[i];
51                 }
52 
53                 preIndex = next; // 从找到的bar开始下一次的迭代
54             } else {
55                 water += (minHeight * (minIndex - preIndex - 1)); // 计算总面积
56 
57                 for (int i = preIndex + 1; i < minIndex; ++i) { // 减去中间bar面积
58                     water -= height[i];
59                 }
60 
61                 preIndex = minIndex; // 从次高的bar开始
62             }
63         }
64 
65         return water;
66     }
67 };
68 
69 int main(int argc, char const *argv[]) {
70     Solution solution;
71     vector<int> height = {0,1,0,2,1,0,1,3,2,1,2,1};
72     cout << solution.trap(height) << endl;
73     return 0;
74 }
Trapping Rain Water

 

闲聊一二

大年初一!祝大家猴年快乐啦,已经工作的童鞋升职加薪,要实习、找工作的童鞋offer多多~博主今年也要面对找实习、找工作的人生大事儿了。好久没写博客了,默默的哀悼上个学期,自己瞎折腾,弄出的不成熟的东西。希望猴年是激情,奋斗,收获的一年~

 

ps:有没有对我感兴趣的boss收留~附交友地址一枚https://github.com/zrss

简单粗暴的resume:https://github.com/zrss/ghostblog,近期再修改下

转载于:https://www.cnblogs.com/hzhesi/p/5185073.html

这篇关于有意思的数学题:Trapping Rain Water的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/206182

相关文章

LeetCode - 11. Container With Most Water

11. Container With Most Water  Problem's Link  ---------------------------------------------------------------------------- Mean:  给你一个N条垂直于x轴的直线,从中找两条直线和x轴组成一个桶状容器,使得这个容器的容量最大. analyse:

LeetCode - 42. Trapping Rain Water

42. Trapping Rain Water  Problem's Link  ---------------------------------------------------------------------------- Mean:  在坐标上给你一些竖直放置的条形积木,问你这个积木能够容纳多少液体. analyse: 首先找出最高的积木,然后从前往后一直

【HDU】2389 Rain on your Parade 二分匹配 Hopcroft-Krap算法

传送门:【HDU】2389 Rain on your Parade 题目分析: 这题目非要我学Hopcroft-Krap= =||。。普通的DFS版的二分匹配不行,最大流又爆内存。。不得不学更好的算法了。 二分匹配的其他性质我也不多说了,不会的自行搜索,网上很多的。 现在我主要对该算法的实现发表一下自己的见解。(算法复杂度的证明不会,论文没看太懂) 该算法的核心思想是通过bfs寻找

数学题--2860. 让所有学生保持开心的分组方法数

2860. 让所有学生保持开心的分组方法数 给你一个下标从 0 开始、长度为 n 的整数数组 nums ,其中 n 是班级中学生的总数。班主任希望能够在让所有学生保持开心的情况下选出一组学生: 如果能够满足下述两个条件之一,则认为第 i 位学生将会保持开心: 这位学生被选中,并且被选中的学生人数 严格大于 nums[i] 。这位学生没有被选中,并且被选中的学生人数 严格小于 nums[i]

P1149 [NOIP2008 提高组] 火柴棒等式(一个比较有意思的题)

P1149 [NOIP2008 提高组] 火柴棒等式 #include <bits/stdc++.h>using namespace std;int n, ans, a[11111]={6, 2, 5, 5, 4, 5, 6, 3, 7, 6};bool vis[11111][11111];int main(){cin >> n;//计算每个数需要的火柴棒for(int i=10;

Container With Most Water (Java实现)

当看见这道题时想到的一个答案就是暴力破解,附上代码 <span style="font-size:18px;"><span style="font-size:18px;">package com.alibaba;import java.util.Scanner;public class Solution{public int maxArea(int[] height){int maxCapac

最常用的SAT数学题解答方法分享

下面为大家总结的是一些最常见的SAT数学题的解答方法。SAT数学题的备考对于中国考生来说难度不是很大,但是如果能够掌握更多的方法,会让大家的答题效果更好,正确率也更高。下面我们来看看详细内容吧。   1. 代入法-----------最常见的方法,适用于所有数学题目,只要是答案中有确切的数目。   例题:If x and y are two different integers and t

【数学题-递推找规律】BNU 4225 杨辉三角形

【题目链接】click here~~ 【题目大意】 LZM 同学比较牛, Lsy 最近也越来越生猛,他们思路快,代码速度神勇。近期惊闻此二人均要参加校赛,队里决定出些题目卡他们,因为他们的罢工给题目组留下了繁重的负担……(报复报复) 于是, XsugarX 瞄准了 LZM 不太喜欢看的数学题目以及 Lsy 猜公式的喜好,奸笑中( ^.^ )。这个数学问题是个比较古老的问题,有如下

C程序设计几个有意思的小例子

1.从键盘输入整数n(n>1),将n分解为若干质数(素数)之积。例如, 当n=10时,输出结果为2,5, 当n=40时,输出结果为2,2,2,5, **代码实现: void fenjie(int n){int i=2; scanf("%d,",n);while (n>i){if(n%i==0){printf("%d,",i);n=n/i;}elsei++;}printf("%d,

有意思的第三方jar包记录

先做个记录,等有时间了可以仔细研究下。 1、org.kie 2、spillway 用于限速