力扣(LeetCode)891. 子序列宽度之和C++)

news2024/7/4 5:54:26

数学推理

贡献法

由题意可知,子序列的内部顺序不影响宽度,所以可以对子序列排序。得到正序序列。
1   2   3   4   5   6 1~2~3~4~5~6 1 2 3 4 5 6 , 序列中数字 4 4 4 的下标 i = 3 i=3 i=3 ,对于数字 4 4 4 , 最大值为 4 4 4 的子序列个数为 2 3 = 2 i 2^3 = 2^i 23=2i , 最大值 4 4 4 左侧数可选可不选,每个数有选或不选 2 2 2 种情况,一共 3 3 3 个数 , 对应 2 3 = 2 i = 8 2^3 = 2^i=8 23=2i=8 种状态。

或者用组合的形式理解, 最大值 4 4 4 固定,而前面有 3 3 3 个数,一共有 C 3 0 + C 3 1 + C 3 2 + C 3 3 = 2 3 C_3^0+C_3^1+C_3^2+C_3^3 = 2^3 C30+C31+C32+C33=23 种状态。推广到 i i i 个数,有 C i 0 + C i 1 + … C i i = 2 i C_i^0+C_i^1+\dots C_i^i = 2^i Ci0+Ci1+Cii=2i 种状态。

同理,以 4 4 4 为最小值的子序列有 2 n − 1 − i 2^{n-1-i} 2n1i 个, n n n 是数字总数 , i i i 是数字下标。

数字 x x x 对答案的贡献 = 2 i × x − 2 n − 1 − i × x = ( 2 i − 2 n − 1 − i ) × x =2^i\times x - 2^{n-1-i}\times x = (2^i-2^{n-1-i})\times x =2i×x2n1i×x=(2i2n1i)×x
统计所有数对答案的贡献,即为所求。

预处理2的幂

class Solution {
private:
    const int mod = 1e9 +7;
public:
    int sumSubseqWidths(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n = nums.size();
        int pow2[n];
        pow2[0] = 1;
        for(int i = 1;i<n;i++) pow2[i] = (pow2[i-1]*2)%mod;//预处理2^i
        long long ans = 0;
        for(int i = 0;i<n;i++) ans =  (ans+(long long)(pow2[i]-pow2[n-1-i]) * nums[i]) % mod;
        return (ans+mod)%mod;
    }
};

时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn) , 时间瓶颈在于排序。预处理 2 2 2 的幂的时间复杂度 O ( n ) O(n) O(n),遍历所有数的时间复杂度 O ( n ) O(n) O(n) , 总时间复杂度 O ( n l o g n + 2 n ) O(nlogn + 2n) O(nlogn+2n)

空间复杂度 O ( n ) O(n) O(n) 预处理2的幂使用了数组存储, 空间复杂度 O ( n ) O(n) O(n) , 快排的空间复杂度 O ( l o g n ) O(logn) O(logn) , 总时间复杂度 O ( n + l o g n ) O(n+logn) O(n+logn)。。

快速幂

class Solution {
private:
    const int mod = 1e9 +7;
public:
    long long qmi(int a,int b ,int p){
        long long ans = 1;
        while(b){
            if(b&1) ans = ans*a%p;
            b>>=1;
            a = (long long)a*a%p;
        }
        return ans;
    }
    int sumSubseqWidths(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n = nums.size();
        long long ans = 0;
        for(int i = 0;i<n;i++) ans =  (ans+(qmi(2,i,mod)-qmi(2,n-1-i,mod))*nums[i]) % mod;
        return (ans%mod+mod)%mod;
    }
};

时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn) ,排序的时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn),遍历所有数的时间复杂度 O ( n ) O(n) O(n),求快速幂的时间复杂度 O ( l o g n ) O(logn) O(logn) , 遍历的同时使用快速幂时间复杂度 O ( l o g n ) O(logn) O(logn) , 总时间复杂度 O ( 3 × n l o g n ) O(3\times nlogn) O(3×nlogn)

空间复杂度 O ( l o g n ) O(logn) O(logn) 快排的空间复杂度 O ( l o g n ) O(logn) O(logn)

转换思路

对上述思想,转换思路,得
2 i 2^i 2i 对答案的贡献为 2 i × ( n u m s [ i ] − n u m s [ n − 1 − i ] ) 2^i\times (nums[i] - nums[n-1-i]) 2i×(nums[i]nums[n1i])

class Solution {
private:
    const int mod = 1e9 +7;
public:
    int sumSubseqWidths(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n = nums.size();
        long long ans = 0;
        long long pow2 = 1;
        for(int i = 0;i<n;i++){
            ans = (ans+(long long)pow2*(nums[i] - nums[n-1-i])%mod) %mod;
            pow2 = (pow2<<1)%mod;
        }
        return (ans%mod+mod)%mod;
    }
};

读者可以想想转换思路的妙处。

时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn) , 时间瓶颈在于排序。遍历所有数的时间复杂度 O ( n ) O(n) O(n) , 总时间复杂度 O ( n l o g n + n ) O(nlogn + n) O(nlogn+n)

空间复杂度 O ( l o g n ) O(logn) O(logn) 快排的空间复杂度 O ( l o g n ) O(logn) O(logn)

博主致语

理解思路很重要!
欢迎读者在评论区留言,作为日更博主,看到就会回复的。

AC

预处理2的幂
快速幂
转换思路

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/14658.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web前端开发技术课程大作业——HTML5旅游景区景点(13页面)HTML+CSS+JavaScript

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

A-Level经济例题解析及练习Computing MPL and VMPL

知识点&#xff1a;Computing MPL and VMPL例题&#xff1a; Question: Computing MPL and VMPL P $5/bushel. Find MPL and VMPL, fill them in the blank spaces of the table. Then graph a curve with VMPL on the vertical axis, L on horizontal axis.解析&#xff1a;…

891. 子序列宽度之和(每日一难phase3-4)

891. 子序列宽度之和 一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。 给你一个整数数组 nums &#xff0c;返回 nums 的所有非空 子序列 的 宽度之和 。由于答案可能非常大&#xff0c;请返回对 109 7 取余 后的结果。 子序列 定义为从一个数组里删除一些&…

简单工厂模式、工厂模式、抽象工厂模式和加入反射、配置优化后的抽象工厂模式之间的关系和区别

通过两张图简单解释一下什么是简单工厂模式、工厂模式、抽象工厂模式 简单工厂模式是属于创建型模式&#xff0c;又叫做静态工厂方法&#xff08;Static Factory Method&#xff09;模式&#xff0c;但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种…

Mac上 Word安装Mendeley插件

Mac上 Word安装Mendeley插件问题背景解决方法针对Mendeley Desktop针对Mendeley Reference Manager参考链接问题背景 可能因如同时安装了Word和WPS等&#xff0c;导致Word上安装Mendeley插件失败&#xff08;Unable to install the Microsoft Word Plugin&#xff09;。目前网…

协同细菌觅食优化算法(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

知识蒸馏IRG算法实战:使用ResNet50蒸馏ResNet18

摘要 复杂度的检测模型虽然可以取得SOTA的精度&#xff0c;但它们往往难以直接落地应用。模型压缩方法帮助模型在效率和精度之间进行折中。知识蒸馏是模型压缩的一种有效手段&#xff0c;它的核心思想是迫使轻量级的学生模型去学习教师模型提取到的知识&#xff0c;从而提高学…

Golang入门笔记(11)—— 包

使用包的原因&#xff1a; 1.不可能把所有的不同业务功能的函数都放在一个源文件中&#xff0c;这样不便于管理。通常的做法是&#xff1a;我们会把具有相同一些功能和业务的维度的函数&#xff0c;分门别类的放在不同的源文件中。 2.不同的包名&#xff0c;可以解决两个函数…

Java面对对象的特征之二:继承性 :why?

一、继承性的好处&#xff1a; 减少了代码的冗余&#xff0c;提高了代码便于功能的扩展为之后的多态性的使用&#xff0c;提高了前提 二、继承性的格式&#xff1a;class A extends B{} A:子类、派生类、subclass B&#xff1a;父类、超类、基类、superclass 提现&#xff1…

数据中台解决方案-最新全套文件

数据中台解决方案-最新全套文件一、建设背景面临的挑战1、数据孤岛2、管理困难3、感知不强4、融合不足5、响应滞后二、思路架构三、建设方案四、获取 - 数据中台全套最新解决方案合集一、建设背景 在数字化转型及大数据战略布局背景下&#xff0c;建设大数据平台及数据应用。其…

idea连接kerberos认证的hive

其实用dbeaver连接hive就可以了。但是呢&#xff0c;idea也有这个功能&#xff0c;本着研究下的想法就试试。 结果最后成功了 最后记录下。 参考文章。感觉不太行 PyCharm,idea通过插件database连接带Kerberos的hive_不饿同学的博客-CSDN博客 里面提到了两个解决办法&#…

D. Non-zero Segments(前缀和)

Problem - 1426D - Codeforces 题意: 科利亚得到一个整数数组a1,a2,...,an。这个数组既可以包含正整数也可以包含负整数&#xff0c;但是Kolya不喜欢0&#xff0c;所以这个数组不包含任何零。 Kolya不喜欢他的数组中某些子段的总和为0&#xff0c;子段是数组中一些连续的元素…

IDR 学习笔记

Multiview Neural Surface Reconstruction by Disentangling Geometry and Appearance 主页&#xff1a;https://lioryariv.github.io/idr/ 论文&#xff1a;https://arxiv.org/abs/2003.09852 代码&#xff1a;https://github.com/lioryariv/idr 效果展示 idr_fountain效果图…

【面试题】循环队列队列实现栈栈实现队列

1️⃣设计循环队列OJ链接 2️⃣用队列实现栈OJ链接 3️⃣用栈实现队列OJ链接 这几道面试题需要栈和队列的知识&#xff0c;它们的相关知识可以看我的上一篇文章 1️⃣设计循环队列 先来了解一下环形队列&#xff0c;这也是循环队列的思想&#xff0c;空间是固定的&#xff0c;数…

Kafka分区策略

默认分区器DefaultPartitioner &#xff08;1&#xff09;指明partition的情况下&#xff0c;直 接将指明的值作为partition值&#xff1b; &#xff08;2&#xff09;没有指明partition值但有key的情况下&#xff0c;将key的hash值与topic的 partition数进行取余得到partiti…

代谢组学——最接近生物表型的组学

■ 什么是代谢组学 在基于基因组-转录组-蛋白质组-代谢组的系统生物学框架内&#xff0c;代谢组学 (metabolomics/metabonomics) 处于最下游&#xff0c;最接近生物表型&#xff0c;主要通过考察生物体系在某一特定时期内受到刺激或扰动前后所有小分子代谢物 (分子量小于 1500…

信创国产化大背景下,应用性能体验如何保障?

信创产业是拉动中国经济增长不可或缺的重要抓手。从2020年我国迈入信创发展元年&#xff0c;到2022年信创开始向行业“深水区”迈进&#xff0c;信创产业得到了国家相关政策的大力支持。今年9月底国家下发79号文&#xff0c;全面指导国资信创产业的发展和进度&#xff0c;明确要…

bootstrap导航窗格响应式二级菜单

这次碰到的需求是响应式二级导航窗格&#xff0c;默认的导航窗格只有点击下拉框的二级窗格&#xff0c;会有如下问题&#xff1a;一级菜单无法添加超链接&#xff0c;二级菜单展示要多点一下。 实现目标&#xff1a; 1.滑动到指定区域&#xff0c;展示二级菜单。 2.一级菜单和…

Vue3 - 响应式工具函数(使用教程)

前言 您需要对 ref()、reactive() 有所了解&#xff0c;否则要先学习这些。 Vue3 为响应式提供了一些工具函数&#xff0c;辅助开发&#xff1a; API说明isRef()检查某个值是否为 ref。isProxy()检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowRe…

前端国际化如何对中文——>英文自动化翻译小demo

非专业的国际化语言。 需求是把zh.js文件中的对象的值转换为en.js&#xff08;也就是实现中英文翻译&#xff09; 结果&#xff1a; 话不多说&#xff0c;上技巧&#xff01; 首先找个免费翻译的API接口&#xff0c;我找的百度翻译的API接口。百度翻译开放平台看百度翻译技术…