每日一题 —— LC. 891 子序列的宽度之和
admin
2024-04-12 04:29:19
0

891. 子序列的宽度之和

一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。

给你一个整数数组 nums ,返回 nums 的所有非空 子序列宽度之和 。由于答案可能非常大,请返回对 109+710^9 + 7109+7 取余 后的结果。

子序列 定义为从一个数组里删除一些(或者不删除)元素,但不改变剩下元素的顺序得到的数组。例如,[3,6,2,7] 就是数组 [0,3,1,6,2,2,7] 的一个子序列。

提示:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^5

示例

输入:nums = [2,1,3]
输出:6
解释:子序列为 [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3] 。
相应的宽度是 0, 0, 0, 1, 1, 2, 2 。
宽度之和是 6 。

思路

暴力是人类最直观的思维,如果要暴力来做,那么就是枚举所有的子序列,然后依次计算每个子序列中的最大值和最小值,求出每个子序列的宽度,然后进行累加。假设数组的长度为n,那么所有子序列的数量就是2n2^n2n,因为生成一个子序列,就是对每个元素进行选择:保留or删除。每个元素有2种选择,则n个元素就一共有 2n2^n2n 种方案。

此题的数据范围是 10510^5105,也就是 n=105n = 10^5n=105。

暴力是一定行不通的。

此时我们转换思维,不从子序列来推最小值最大值,而从最小值最大值来推子序列。

什么意思呢?就是对于数组中的某个元素,我们计算一下,这个元素作为最小值的子序列,有多少个;这个元素作为最大值的子序列,又有多少个。我们要求的是所有子序列的最大值减最小值的。那么我们就能算出这个元素对于最终答案的贡献。假设这个元素为a,以a作为最小值的子序列共有L个,以a作为最大值的子序列共有R个,那么该元素对答案的贡献就是 a × (R - L)

我们只要对数组中每个元素,计算一下其对答案的贡献,然后进行一下累加即可。


关键点一:不从子序列来推最小值最大值,而从最小值最大值来推子序列


然后,对于某个子序列,我们只关心它的两个最值,那么子序列内部元素的顺序就无关紧要。比如,子序列 1 3 5 7和子序列5 7 3 1,我们其实可以将其看成等价,这并不会影响最终答案的正确性。

所以,我们可以对整个数组先排个序。

为什么要排序呢?因为排序后能够很方便的计算某个元素作为最大值和最小值的子序列的个数!


关键点二:顺序无关


排完序后,对于某个位置i的数,它比[0, i - 1]的所有数都大,比[i + 1, n - 1]的所有数都小。(这里其实不是严格的大小关系,因为有可能存在相等的元素)。

也就是说,[0, i]中第i个数是最大值(可能有相等的但不影响),[i, n - 1]中第i个数是最小值。

由于某个子序列,是保留一些数,和删去一些数。那么第i个数作为最大值的子序列,一定需要保留第i个数,对于前面的[0, i - 1]区间的数,每个数都有保留或者不保留的选择,那么能形成的子序列数量是 2i2^{i}2i;所以以第i个数作为最大值的子序列的个数是 2i2^i2i;同理,对于以第i个数作为最小值的子序列,一定要保留第i个数,对于后面的[i + 1, n - 1]区间内的每个数,都有保留或者不保留的选择,那么能形成的子序列数量是 2n−1−i2^{n - 1 - i}2n−1−i;

那么第i个数对答案的贡献就是 (2i−2n−1−i)×nums[i](2^i-2^{n-1-i}) × nums[i](2i−2n−1−i)×nums[i]


关键点三:排序后,推公式


所以,我们可以进行一次遍历,挨个累加每个元素的贡献,就能得到最终的答案

// C++
typedef long long LL;
const int MOD = 1e9 + 7;
class Solution {
public:// 快速幂LL qmi(LL a, LL b, LL p) {LL t = a, ans = 1;while (b) {if (b & 1) ans = (ans * t) % p;b >>= 1;t = (t * t) % p;}return ans;}// 每个值作为最小值的序列个数// 每个值最为最大值的序列个数// 计算每个值对答案的贡献int sumSubseqWidths(vector& nums) {sort(nums.begin(), nums.end());LL mi = 0, ma = 0; // 最小值的和, 最大值的和int n = nums.size();for (int i = 0; i < n; i++) {// 组合数求和Cn0+Cn1+...+Cnn = 2^n// nums[i]作为最大值的子序列个数ma = (ma + qmi(2, i, MOD) * nums[i]) % MOD;// nums[i]作为最小值的子序列个数mi = (mi + qmi(2, n - 1 - i, MOD) * nums[i]) % MOD;}return (int) ((ma - mi + MOD) % MOD);}
};

小结

本题是上周五的每日一题。

当按正向的直观的逻辑无法求解时,可以逆向思考,考虑单个元素对整体答案的贡献值。

运用这样思维的题目,还有10月底某天的每日一题(907. 子数组的最小值之和),以及今天(2022/11/24)的每日一题(795. 区间子数组个数),这两道题都可以采用这样的思维,加上单调栈,进行求解。

相关内容

热门资讯

邱淑贞丈夫花费4200万购入半... 沈嘉伟又出手了,4200万港元,中半山地利根德阁3座中层B室,实用面积1602平方呎,三房连一套房。...
Meta拟聘请亚马逊云科技高管... 7月17日消息,据财联社获悉,亚马逊云科技(AWS)资深高管戴夫·布朗即将入职Meta。 据知情人士...
一场年中大促后,美国兴趣电商走... 封面图片由AI生成 海外“618”,兴趣电商在美国的一次大考。 对关注美区的跨境卖家来说,年中大促季...
原创 半... 半年回撤近三成,金价大幅回调,四大核心信号辨别本轮行情属性 很多普通投资者最近都十分困惑,年初还一路...
原创 中... 近期全球黄金市场出现反常一幕:国际金价今年早些时候冲高后已下跌近 30%,但中国市场却掀起了一股购金...
原创 从... 顶着“人类太空希望”光环的SpaceX,连续三个交易日股价下挫,跌破 IPO 发行价。过去的Spac...
【数智化人物展】衡石科技创始人... 刘诚忠 “【提示】2026第六届数智化颁奖典礼将于8月5日在北京举行颁奖点击可报名参加颁奖典礼丨此次...
泽连斯基一个拧瓶盖动作,违反了... 在今天的欧洲,有什么行为能让你瞬间成为“环保罪人”? 答案荒诞得像个段子:你只要把塑料瓶盖完完整整地...
阿里巴巴香港创业者基金何定康:... 【导读】NextGen Partners 合伙人何定康 (Kenny Ho) 认为,全球投资者已形成...
早睡早起和晚睡晚起,到底谁更健... 很多人都有过这样的自我安慰:虽然我凌晨两点才睡,但第二天睡到上午十点,照样睡满8小时,应该不算熬夜。...
LV老板被责令补税,高达1.7... 7月17日消息,据中新经纬,近日,在一场持续多年的法律诉讼后,法国首富、LVMH掌门人贝尔纳·阿尔诺...
原创 黄... 来源 | 《财经》新媒体 文丨《财经》新媒体研究员 蒋金丽 编辑丨蒋诗舟 经历了短暂反弹后,国际金价...
Atlas关停,AI浏览器没有... 根据OpenAI官方文档,Atlas将于2026年8月9日停止运行。用户需要提前迁移想保留的数据,包...
心理咨询师2026年小红书导流... 「小红书公转私」是指在小红书平台上,通过合规的内容运营和互动策略,将公域流量用户引导至微信等私域渠道...
小鹏就空气弹簧故障致歉,小米汽... 今天是 7 月 17 日 农历六月初四 杭州怎么就 38 度了 这个天气 一出门就感觉 正在被低温慢...
光模块龙头中际旭创通过港交所聆... 7月17日,港交所披露文件显示,全球高速光模块龙头中际旭创顺利通过主板上市聆讯,距离完成A+H两地上...
2026年A股最大IPO来了,... 7月16日,中国存储芯片龙头长鑫科技正式开启网上申购。这家存储芯片龙头企业,即将创下今年A股最大IP...
西部利得基金旗下一基金成立15... 深圳商报·读创客户端记者 詹钰叶 西部利得基金旗下最“资深”产品西部利得策略优选近来引起投资者关注—...
振石股份:548.86万股首发... 7月17日, 振石股份(601112.SH)公告称,本次上市流通的限售股为首次公开发行网下配售限售股...
解码上半年外汇收支:涉外收支破... 来源:21世纪经济报道 21世纪经济报道 记者郭聪聪 7月17日上午,国新办举行2026年上半年外汇...