这个题直接暴力求解的话时间复杂度肯定是不行的,所以,我们要计算每个数值的贡献,对每一个数求他当最小值当了多少次,当最大值当了多少次,最后当最大值的次数乘以这个数值减去当最小值的次数乘以数值就得到这个数的贡献,依次把这n个数的贡献加起来就是整个极差之和。

在计算一个数当了多少最值的时候,我们要理解问题,因为区间是连续的,所以,以最小值为例,如果一个数是当前这段区间的最小值,那么他一定是当前这段区间最小的(这不废话),所以,我们就找到他往左做多能找到多少个连续的数都比他大,记录这个位置,同理找他右边有多少个大于它的,这样就得到一个区间,这个区间是以这个数位最小值,如下图示可以比较直观的理解。

加入找以2为最小值的区间,那么他最多可以往左找到3,往右最多可以找到5,那么2作为最小值构成的区间数目为(2+1) * (1+1),如下:

[3, 9, 2], [9, 2], [2], [3, 9, 2, 5], [9, 2, 5], [2, 5]

同理如果2作为最大值也一样求,最大值区间只有[2]这个区间

这个题目还有一个小技巧就是在预处理每个元素作为最值时,最左到什么位置和最右到什么位置,可以利用已知信息,就是前一个求出的位置来跳着加速,使得时间复杂度不是O(n^2)

代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
int a[maxn];
int L[maxn], R[maxn];
void print(int L[], int n)
{for (int i = 1; i <= n; i++)printf("%d ", L[i]);puts("");
}
int main()
{int n;scanf("%d", &n);for (int i = 1; i <= n; i++)scanf("%d", &a[i]);a[0] = -1, a[n + 1] = -1;int sum_min = 0;//求以当前元素作为最小值时,最左可以扩展到的元素位置.for (int i = 1; i <= n; i++){if (a[i] >= a[i - 1])L[i] = i;else{int tmp = i - 1;while (a[i] < a[tmp]){if (tmp == L[tmp])tmp--;elsetmp = L[tmp];}L[i] = tmp + 1;}}//print(L, n);//求以当前元素作为最小值时,最右可以扩展到的元素位置.for (int i = n; i >= 1; i--){if (a[i] >= a[i + 1])R[i] = i;else{int tmp = i + 1;while (a[i] < a[tmp]){if (tmp == R[tmp])tmp++;elsetmp = R[tmp];}R[i] = tmp - 1;}}//print(R, n);//求作为最小值时每个元素的贡献,最后需要减去for (int i = 1; i <= n; i++){int tmp = (i - L[i] + 1) * (R[i] - i + 1);sum_min += tmp * a[i];}a[0] = inf, a[n + 1] = inf;int sum_max = 0;//求以当前元素作为最大值时,最左可以扩展到的元素位置.for (int i = 1; i <= n; i++){if (a[i] <= a[i - 1])L[i] = i;else{int tmp = i - 1;while (a[i] > a[tmp]){if (tmp == L[tmp])tmp--;elsetmp = L[tmp];}L[i] = tmp + 1;}}//print(L, n);//求以当前元素作为最大值时,最右可以扩展到的元素位置.for (int i = n; i >= 1; i--){if (a[i] <= a[i + 1])R[i] = i;else{int tmp = i + 1;while (a[i] > a[tmp]){if (tmp == R[tmp])tmp++;elsetmp = R[tmp];}R[i] = tmp - 1;}}//print(R, n);//元素作为最大值时的贡献for (int i = 1; i <= n; i++){int tmp = (i - L[i] + 1) * (R[i] - i + 1);sum_max += tmp * a[i];}printf("%d\n", sum_max - sum_min);return 0;
}

View Code

转载于:https://www.cnblogs.com/Howe-Young/p/9499373.html

求数组所有区间最大值减去最小值之差的和(贝壳笔试题)相关推荐

  1. 求数组里面的最大值和最小值

    题目: 求数组里面的最大值和最小值 比如:数组 1,2,3,4,5 最大值是5,最小值是1 代码实现: #include <stdio.h> int max,min; void getMa ...

  2. 求数组中数的最大值、最小值(C语言)

    求数组中数的最大值.最小值(C语言) #include<stdio.h>void main(void) {int num[10],i,imax,imin,imaxp,iminp;for(i ...

  3. 编程之美4:求数组中的最大值和最小值

    方法1:暴力方法 遍历一遍数组,比较2*N次求出最大值和最小值 方法2:改进方法 (破坏了原数组)             遍历一遍数组使得下标为偶数的元素较下标为奇数的元素大,再分别求出最大值和最小 ...

  4. 如何求数组中的最大值或最小值

    对于普通的数求大小,我们之前已经做过了,那对于如今的数组,我们该如何求数组中最大的元素呢?我们可以这么想,数组就是一组数,只要,我们在这组数中选取一个值,然后让它依次和其他的数进行大小比较,当它小于其 ...

  5. 二维数组求最小值_05-最大子矩形-最大值减去最小值小于或等于num的子数组数量...

    年轻即出发... 简书:https://www.jianshu.com/u/7110a2ba6f9e 知乎:https://www.zhihu.com/people/zqtao23/posts Git ...

  6. 编写两个函数,分别求10个元素数组的最大和最小值的下标,并在main函数中运行,求出最大值和最小值之差

    #include<stdio.h> int Max(int a[10]) {int i, m=0, max = a[0];//定义max的初始值为a[0]for(i=1;i<10;i ...

  7. 算法设计——用分治法查找数组元素的最大值和最小值、用分治法实现合并排序、最小费用问题、树的最大连通分支问题(代码实现)

    代码链接:pan.baidu.com/s/15inIth8Vl89R1CgQ_wYc2g  提取码:gf13 算法分析与设计第 1 次实验 时间 2020.3.31 地点 软件大楼 127 实验名称 ...

  8. 寻找数组中的最大值和最小值

    解法1. 我们可以吧数字中的最大值和最小值看成两个独立的问题分别求出数组中的最大值和最小值. 直接的方法就是扫描数字,找到最大数以及最小数. <span style="font-siz ...

  9. 最大值减去最小值小于或等于num的子数组数量

    题目:给定数组arr和整数num,共返回有多少个子数组满足如下情况:子数组中的最大值减去最小值小于或等于num. 要求,时间复杂度O(N). 基本思路: 首先明确两点: 1.如果子数组arr[i-j] ...

最新文章

  1. 用grep命令查找文件中带特定扩展名的字符串
  2. HashMap(Java)
  3. Log4J入门教程(三) web项目的log4j配置
  4. 经典插花的教训 PKU 1157
  5. Vue基础学习(一)------内部指令
  6. AciveMQ小结|最后有视频
  7. 实名羡慕,国内这些厂.NET薪资高的吓人!
  8. 关于.NET5在IIS中部署的几个问题总结
  9. 【渝粤教育】电大中专测量学作业 题库
  10. Jenkins之Log Parse的使用
  11. C#获取MySql 数据常用的代码
  12. html网页设计语言基础教程,HTML 网页设计新手入门教程(共32课时)_IT教程网
  13. App Store与苹果签名
  14. VMware导入vmdk格式的文件 踩了一堆坑~~~
  15. 常见的网络摄像机方案
  16. iOS NSString,NSLog添加%百分号和引号等符号
  17. 开源项目管理软件排名_2014年排名前5位的开源项目管理工具
  18. c语言微信小程序编程,微信小程序实现类似微信点击语音播放效果
  19. STM32驱动3.97寸TFT液晶触摸屏模块
  20. 证券公司信息化12-IT基础设施2-什么是局域网?什么是广域网?CCNP是什么证书?电信能提供长途数据线路吗?

热门文章

  1. Flutter 萌新高频问题(加班猿妈妈叫你回家吃饭了)
  2. Dive Into Thrift Node-安装
  3. Cisco 2811 语音网关+callmanager拨打外线详解配置
  4. HTML怎么让img 等比例缩放
  5. 提高Objective-C代码质量心机一:简化写法
  6. Python:监控键盘输入、鼠标操作,并将捕获到的信息记录到文件中
  7. 在web应用程序中使用MemcachedClient
  8. mysql 表名通配符导出,mysqldump只有某些前缀/ Mysqldump通配符的表?
  9. python3 协程 写法_理解Python的协程(Coroutine)
  10. Unity3d查找游戏对象