GEEK编程练习— —雨水存储问题

题目

给定n个非负整数,分别代表围栏的高度,计算给定的这组数字代表的围栏能够容纳多少水,如图所示。

输入

0 1 0 2 1 0 1 3 2 1 2 1 

输出

6

分析

对于每个柱子,找到其左右两边最高的柱子,该柱子能容纳的面积是min(max_left, max_right) - height。所以可以先扫描一遍,找到最高的柱子,将数组分为两半,然后分别进行处理。

代码

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> bars = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};

    int height = 0;

    //寻找最高的柱子
    for (int i = 0; i < bars.size(); i++)
        if (bars[i] > bars[height])
            height = i;

    int water = 0;

    //左边储水量
    for (int i = 0, peak = 0; i < height; i++)
        if (bars[i] > peak)
            peak = bars[i];
        else
            water += peak - bars[i];

    //右边储水量
    for (int i = bars.size() - 1, top = 0; i > height; i--)
        if (bars[i] > top)
            top = bars[i];
        else
            water += top - bars[i];

    cout << water << endl;

    return 0;
}
时间: 2024-10-11 11:00:59

GEEK编程练习— —雨水存储问题的相关文章

GEEK编程练习— —两数求和

题目 输入一个特定整数值和一组整数,要求从这组整数中找到两个数,使这两数之和等于特定值.按照从前往后的顺序,输出所有满足条件的两个数的位置.具体格式如下: 输入 9 1 2 4 5 7 9 11 输出 2 5 3 4 分析 1)暴力解法,复杂度O(n^2),不考虑 2)hash.用哈希表存储每个数对应下标,复杂度O(n) 3)先排序,然后左右夹逼,排序O(nlogn),夹逼O(n),最终O(nlogn).但是需要的是位置,而不是数字本身,此方法不适用. 代码 #include <iostream

GEEK编程练习— —四数求和

题目 输入一个特定整数s和一组整数,要求从这组整数中找到四个数a,b,c,d,使a+b+c+d=s.按照升序排列,输出所有满足条件的a,b,c,d.具体格式如下: 输入 0 1 0 -1 0 -2 2 输出 -2 -1 1 2 -2 0 0 2 -1 0 0 1 分析 先排序,可以用hashmap缓存两个数的和,然后左右夹逼,时间复杂度O(n^2),空间复杂度O(n^2) 代码 #include <iostream> #include <vector> #include <u

GEEK编程练习— —最长相同的子串

题目 输入一行字符串,找出其中出现的相同且长度最长的字符串,输出它及首字符的位置. 输入 yyabcdabjcabceg 输出 abc 3 解析 首先声明一下,假如字符串为aaaaaa,答案应该为aaaaa.两个个等长的子串可以有部分字符重叠. 以abcab为例子分析如下: 首先寻找长度为4的子串,只能是abca和bcab,再查看这两个子串是否有其他相同的子串.有的话直接输出结果并退出程序. 然后寻找长度为3的子串,只能abc,bca,cab.这3个子串都没有其他相同的子串. 最后寻找长度为2的

GEEK编程练习— —zigzag矩阵

题目 输入矩阵规模N,输出zigzag矩阵. zigzag顺序为下图所示 输入 5 输出 0 1 5 6 14 2 4 7 13 15 3 8 12 16 21 9 11 17 20 22 10 18 19 23 24 解析1 此方法是计算顺序位置的对应元素值. 假定i为行数,j为列数,每一条斜线下标(i+j)为常数,记为s(s=i+j). 处理分为上三角和下三角两部分处理. 对于上三角,每一个斜线上的元素个数比上一斜线多一个,每个斜线上的第一个元素表示了该斜线之前元素的个数.运用等差数列求和公

GEEK编程练习— —最长连续序列

题目 给定一个无序的整数数组,返回最长连续序列的长度.要求时间复杂度为O(n). 输入 [100, 4, 200, 1, 3, 2, 0, -1] 输出 6 分析 因为要求时间负责度为O(n),所以不能先排序再查找.所以想到查询最快的hash表,记录每个元素是否使用,对每个元素,往左右扩张,直到不连续为止. 代码 #include <iostream> #include <unordered_map> #include <algorithm> using namespa

GEEK编程练习— —发糖果问题

题目 假设N个小孩站成一排,每个小孩被分配了一个整数号码.要按照如下的要求给孩子们发糖. 1.每个小孩至少有一颗糖果 2.号码大的孩子比相邻的孩子分到的糖果要多 求最少要发出几颗糖果 输入 0 1 3 1 4 输出 9 分析 可以前后循环两遍,第一遍从前往后,把相邻的两个小孩中,前面号码比后面号码大的多发糖:第二遍从后往前,同样把相邻孩子中,后面号码比前面号码大的多发糖:最后加和得到结果. 代码 #include <iostream> #include <vector> #incl

GEEK编程练习— —三数求和

题目 输入一个特定整数s和一组整数,要求从这组整数中找到三个数a,b,c,使a+b+c=s.按照升序排列,输出所有满足条件的a,b,c.具体格式如下: 输入 0 -1 0 1 2 -1 -4 输出 -1 -1 2 -1 0 1 分析 先排序,然后左右夹逼,复杂度O(n^2) 此方法可以推广到k个数求和,先排序,做k-2次循环,在最内层循环左右夹逼,时间复杂度O(max(nlogn,n^(k-1))) 代码 #include <iostream> #include <vector>

GEEK编程练习— —格雷码

题目 格雷码是一种二进制数值系统.在一组数的编码中,任意两个相邻的代码只有一位二进制数不同.给定一个非负整数n表示格雷码的位数,输出所有格雷码. 格雷码序列从0开始.格雷码不唯一. 输入 2 输出 00 01 11 10 分析 结果要输出二进制形式,可以使用bitset,这里设置最大位数为128位,可根据情况修改.格雷码公式为a ^ (a - 1) 代码 #include <iostream> #include <bitset> using namespace std; int m

MySQL编程基础

存储过程 什么是存储过程 存储过程(Stored Procedure)是在大型数据库系统中,一个或多个为了完成特定功能的SQL 语句集(可以视为批处理文件),经编译后存储在数据库中. 创建存储过程 delimiter $ create procedure sp_name ([参数,参数..]) begin 执行体 end delimiter ; 其中,create procedure 为用来创建存储过程的关键字 sp_name为存储过程的名称 begin...end为存储过程执行代码的开始和结束