每日一题 —— 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. 区间子数组个数),这两道题都可以采用这样的思维,加上单调栈,进行求解。

相关内容

热门资讯

成分股集体上涨,港股通汽车ET... 截至2月24日14点10分,上证指数涨0.89%,深证成指涨1.41%,创业板指涨1.11%。ETF...
韩国股指再刷新历史新高!2月最... 来源:财联社 财联社2月23日讯(编辑 马兰)周一,受益于美国对等关税政策无效、人工智能热潮继续刺激...
影石开工红包:每人100,到岗... 2月24日消息,影石为员工安排开工红包,每人100,当天到岗就有。 据介绍,该红包由部门leader...
太疯狂!“现在至少要10万”,... 2月24日早盘,贵金属盘初直线飙升。现货黄金突破5240美元/盎司,触及三周高点,纽约期金突破526...
别盲目跟风!华工科技赶单忙到疯... 最近华工科技涨得有点猛,身边不少人问我是不是又在炒概念。其实吧,这次真不是瞎炒,背后有实打实的订单撑...
韩广岳再辞任董事长职务,李学军... 近日,中邮资管发布公告称,因年龄原因,韩广岳正式向董事会提交辞去公司董事长、董事会投资决策委员会主任...
2026年中国智能舒缓穿戴设备... 华经产业研究院为助力企业、科研、投资机构等单位了解智能舒缓穿戴设备行业发展态势及未来趋势,特重磅推出...
茅台带动春节白酒价格触底止跌,... 虽然业内对2026年春节白酒市场有着“最冷”的担忧,但记者了解到,在茅台的带动下,尽管白酒市场整体需...
广东省情中心:广东生产性服务业... 2月24日,春节后首个工作日,广东连续第四年召开全省高质量发展大会,今年聚焦“制造业与服务业协同发展...
2022三文鱼行业及市场洞察报... 今天分享的是:2022三文鱼行业及市场洞察报告 报告共计:32页 三文鱼作为一种备受青睐的高端水产,...
AI芯片新突破 12只概念股获... 来源:证券时报e公司 人民财讯2月24日电,据科技日报2月23日报道,北京大学电子学院研究员邱晨光团...
原创 不... 特朗普突然改口,全球关税在短时间内再度上调5%,引发市场与舆论的广泛关注。有分析指出,在这一轮博弈中...
湖南三线小城春节消费火爆,商场... 常德街道。胡雅文/摄 本报(chinatimes.net.cn)记者胡雅文 常德报道 马年春节,常德...
小红书负面笔记处理|品牌舆情优... 在当下的社交媒体版图中,小红书早已超越单纯的“种草社区”定位,成长为月活跃用户突破3亿、每日新增笔记...
原创 俄... 最近,国际金融圈发生了一件让许多观察者都感到摸不着头脑的大事——俄罗斯正在源源不断地将黄金运往东方,...
知名食品上市公司实控人陈飞龙去... 2月23日晚间,南侨食品(SH605339)公告称,公司董事会收到公司实控人之一陈飞龙家属通知,陈飞...
高开高走!马年首日三大股指半日... 金融投资报记者 林珂 马年首个交易日大盘如期高开高走,早盘三大股指均出现超过1%的涨幅。 上证指数...
千亿市值巨头,涨停 马年首个交易日,A股主要指数早盘集体上涨。截至午盘,沪指涨1.17%,深证成指涨1.82%,创业板指...
匈牙利外长:决定向谁买能源是主... 据央视新闻报道,欧盟成员国外长2月23日未能就第20轮对俄罗斯制裁方案达成一致。匈牙利外交与对外经济...
IC外汇平台:日本经济长期疲软... 根据国际清算银行数据,今年1月日元实际有效汇率指数降至67.73,创1973年以来最低。该指数反映日...