C++前缀和算法的应用:统计上升四元组

C++前缀和算法的应用:统计上升四元组

本文涉及的基础知识点

C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频

题目

给你一个长度为 n 下标从 0 开始的整数数组 nums ,它包含 1 到 n 的所有数字,请你返回上升四元组的数目。
如果一个四元组 (i, j, k, l) 满足以下条件,我们称它是上升的:
0 <= i < j < k < l < n 且
nums[i] < nums[k] < nums[j] < nums[l] 。
示例 1:
输入:nums = [1,3,2,4,5]
输出:2
解释:

  • 当 i = 0 ,j = 1 ,k = 2 且 l = 3 时,有 nums[i] < nums[k] < nums[j] < nums[l] 。
  • 当 i = 0 ,j = 1 ,k = 2 且 l = 4 时,有 nums[i] < nums[k] < nums[j] < nums[l] 。
    没有其他的四元组,所以我们返回 2 。
    示例 2:
    输入:nums = [1,2,3,4]
    输出:0
    解释:只存在一个四元组 i = 0 ,j = 1 ,k = 2 ,l = 3 ,但是 nums[j] < nums[k] ,所以我们返回 0 。
    参数范围
    4 <= nums.length <= 4000
    1 <= nums[i] <= nums.length
    nums 中所有数字 互不相同 ,nums 是一个排列。

容易理解

分析

第一层循环,枚举j,第二层循环枚举k。时间复杂度O(n*n)。在通过不通过之间,用vector<vector>就通过不了,用int**勉强可以通过。分两步:

第一步求前缀和
第二步枚举j和k

核心代码

class Solution {
public:
long long countQuadruplets(vector& nums) {
m_c = nums.size();
int** vSum = new int*[m_c + 1];//vSum[i][j]:nums[0,j)中小于等于i的个数
for (int i = 1; i <= m_c; i++)
{//计算小于i的个数
vSum[i] = new int[m_c+1];
vSum[i][0] = 0;
for (int j = 0 ; j < m_c; j++ )
{
vSum[i][j+1] = vSum[i][j] + (nums[j] <= i);
}
}
long long llRet = 0;
for (int j = 1; j < m_c; j++)
{
for (int k = j + 1; k+1 < m_c; k++)
{
if (nums[j] < nums[k])
{
continue;
}
//nums[i]范围:nums[0,j)中小于等于nums[k]的数量
const long long lessNumK = vSum[nums[k]][j];
//nums[k+1,m_c)中大于nums[j]
const long long moreNumJ = m_c - (k + 1) - (vSum[nums[j]][m_c]- vSum[nums[j]][k+1]);
llRet += lessNumK * moreNumJ;
}
}
return llRet;
}
int m_c;
};

测试用例

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

int main()
{
Solution slu;
vector nums ;
long long res;
nums = { 1, 3, 2, 4, 5 };
res = slu.countQuadruplets(nums);
Assert(2LL, res);
nums = { 1, 2,3,4 };
res = slu.countQuadruplets(nums);
Assert(0LL, res);
nums = { 4,3,2,1 };
res = slu.countQuadruplets(nums);
Assert(0LL, res);
nums = { 4,3,2,6,5,1 };
res = slu.countQuadruplets(nums);
Assert(0LL, res);
nums = { 1,3,2,4 };
res = slu.countQuadruplets(nums);
Assert(1LL, res);
nums = { 2,1,4,3,5 };
res = slu.countQuadruplets(nums);
Assert(2LL, res);
nums.clear();
for (int i = 0; i < 4000; i++)
{
nums.emplace_back(i + 1);
}
res = slu.countQuadruplets(nums);
Assert(0LL, res);
//CConsole::Out(res);
}

性能稍强

分析

第一层循环,枚举l或k;第二层循环,枚举j。时间复杂度O(n*n),代码简洁得多,可以轻松通过。

变量解释

llRet所有符合条件的四元祖
iLessLKnums[0,j)中小于nums[i]的数量
m_v132[j]nums[0,i)中符合i,j,k的数量

核心代码

class Solution {
public:long long countQuadruplets(vector<int>& nums) {m_c = nums.size();long long llRet = 0;vector<long long> m_v132(m_c);//132for (int lk = 0; lk < m_c; lk++){int iLessLK = 0;for (int j = 0; j < lk; j++){if (nums[j] < nums[lk]){iLessLK++;llRet += m_v132[j];}else{//iLessLK 表示[0,j)中小于nums[lk]的数,假定其索引为i,则nums[i] < nums[lk] ,nums[j] < nums[lk],故i j lk,符合前三个数i,j,km_v132[j] += iLessLK;}}}return llRet;}int m_c;
};

2月旧代码

class Solution {
public:
long long countQuadruplets(vector& nums) {
m_c = nums.size();
//vLeft[i][m] 表示nums[i]及之前的元素,小于等于m+1的个数
int vLeft[4000][4000] = { 0 };
{
for (int i = 0; i < m_c; i++)
{
if (i > 0)
{
memcpy(vLeft[i], vLeft[i - 1], sizeof(vLeft[0]));
}
for (int j = nums[i] - 1; j < m_c; j++)
{
vLeft[i][j] ++;
}
}
}
long long llRet = 0;
for (int j = 1; j + 1 < m_c; j++)
{
for (int k = j + 1; k + 1 < m_c; k++)
{
if (nums[j] <= nums[k])
{
continue;
}
const int iLeft = vLeft[j - 1][nums[k] - 1];
const int iRight = nums[j] - vLeft[k][nums[j] - 1];
llRet += vLeft[j - 1][nums[k] - 1] * (nums.size() - k - 1 - iRight);
}
}
return llRet;
};
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《闻缺陷则喜算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

充满正能量得对大家说
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
墨家名称的来源:有所得以墨记之。
算法终将统治宇宙,而我们统治算法。《喜缺全书》

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开

发环境: VS2022 C++17

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于网站安全的一些讨论

互联网的普及和发展为企业和个人提供了巨大的机会&#xff0c;但同时也伴随着网络安全威胁的增加。网站被攻击是一个常见的问题&#xff0c;可能导致数据泄露、服务中断和声誉受损。在本文中&#xff0c;我们将探讨与网络安全紧密相关的因素&#xff0c;分析为什么网站容易受到…

Si4010 一款带有MCU SoC RF发射机芯片 无线遥控器

Si4010是一款完全集成的SoC RF发射机&#xff0c;带有嵌入式CIP-51 8051 MCU&#xff0c;专为1GHz以下ISM频带设计。该芯片针对电池供电的应用进行了优化&#xff0c;工作电压为1.8至3.6 V&#xff0c;待机电流小于10 nA的超低电流消耗。高功率放大器可提供高达10 dBm的输出功率…

Linux Crontab 定时任务

crond 服务 Linux 通过 crond 服务来支持 crontab。 查看 crond 服务是否已经安装 输入下面命令确认 crond 服务是否已安装。 systemctl list-unit-files | grep crond 如果为 enabled&#xff0c;表示服务正运行。 crontab 文件 crontab 要执行的定时任务都被保存在 /etc…

seata1.8安装部署

1.在nacos里面创建命名空间 2.下载seata安装包 3.将下载的seata解压&#xff0c;找到seata/script/server/db目录下对应数据库的sql脚本&#xff0c;创建数据库 undo_log.sql CREATE TABLE undo_log (branch_id bigint(20) NOT NULL COMMENT branch transaction id,xid varcha…

3线SPI驱动 HX8347 TFT屏

老五家2.8寸屏&#xff0c;3线SPI驱动 前言 要知道屏幕的驱动芯片都小的惊人&#xff0c;想必是不会打上丝印的。从几百个引脚中判断哪个是哪个&#xff0c;想想就晕。 大佬们都太厉害了&#xff0c;看看PFC就知道屏幕的接线定义。一直好奇这种神技是怎么练成的。也尝试自己来…

字符型液晶显示器LCD 1602的显示控制(Keil+Proteus)

前言 趁机把LCD 1602的实验完成了&#xff0c;那个电路图有几个地方没弄懂&#xff0c;但是去掉也没有报错&#xff0c;就没管了。 LCD1602_百度百科 (baidu.com)https://baike.baidu.com/item/LCD1602/6014393?frge_ala LCD1602液晶显示屏通过电压来改变填充在两块平行板之…

动态规划专题——背包问题

&#x1f9d1;‍&#x1f4bb; 文章作者&#xff1a;Iareges &#x1f517; 博客主页&#xff1a;https://blog.csdn.net/raelum ⚠️ 转载请注明出处 目录 前言一、01背包1.1 使用滚动数组优化 二、完全背包2.1 使用滚动数组优化 三、多重背包3.1 使用二进制优化 四、分组背包…

混合云中 DevOps 的最佳实践

近年来&#xff0c;出现了各种工具、技术和框架&#xff0c;其目标是增强灵活性、性能和可扩展性。传统的整体方法已被微服务和纳米服务等更加模块化的方法所取代。此外&#xff0c;云计算的兴起导致本地软件被云环境所取代&#xff0c;云环境提供了以前无法提供的广泛优势和功…

Qwt QwtThermo绘制温度计

1.简介 QwtThermo 是一个基于 Qt 框架的类库&#xff0c;用于创建温度计控件。它提供了一些方便的功能来展示和处理温度计相关的数据。 QwtThermo 添加了特定于温度计的功能。 使用 QwtThermo&#xff0c;可以实现以下功能&#xff1a; 设置温度范围&#xff1a;可以通过设置…

【EI会议征稿】第四届智慧城市工程与公共交通国际学术会议(SCEPT 2024)

第四届智慧城市工程与公共交通国际学术会议&#xff08;SCEPT 2024&#xff09; 2024 4th International Conference on Smart City Engineering and Public Transportation 第四届智慧城市工程与公共交通国际学术会议&#xff08;SCEPT 2024&#xff09;将于2024年1月26-28日…

折叠旗舰新战局:华为先行,OPPO接棒

乌云中的曙光&#xff0c;总能带给人希望。 全球智能手机出货量已经连续八个季度下滑&#xff0c;行业里的乌云挥之不散。不过&#xff0c;也能看到高端市场逆势上涨&#xff0c;散发光亮。个中逻辑在于&#xff0c;当前换机周期已经达到了34个月&#xff0c;只有创新产品才能…

【ARFoundation学习笔记】平面检测

写在前面的话 本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。难免出现纰漏&#xff0c;更多详细内容请阅读原文。 文章目录 平面检测属性可视化平面平面检测的开关控制显示与隐藏已检测平面 平面检测属性 AR中检测平面的原理&#xff1a;AR Fou…

洛谷P1024 [NOIP2001 提高组] 一元三次方程求解(优雅的暴力+二分,干净利落)

P1024 [NOIP2001 提高组] 一元三次方程求解 前言题目题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 题目分析注意事项 代码后话额外测试用例样例输入 #2样例输出 #2 王婆卖瓜 题目来源 前言 没有前言&#xff0c;可能因为作者忘了编辑 题目 题目描述 有形如&…

使用Redis实现缓存及对应问题解决

一、为什么需要Redis作缓存&#xff1f; 在业务场景中&#xff0c;如果有些数据需要极高频的存取&#xff0c;每次都要在mysql中查询的话代价太大&#xff0c;假如有一个存在于客户端和mysql之间的存储空间&#xff0c;每次可以在这空间中进行存取操作&#xff0c;就会减轻mys…

简单工厂模式、工厂方法模式、抽象工厂模式

简介 将实例化代码提取出来&#xff0c;放到一个类中统一管理和维护&#xff0c;达到和主项目依赖关系的解耦&#xff0c;从而提高项目的扩展性和维护性。 工厂模式将复杂的对象创建工作隐藏起来&#xff0c;而仅仅暴露出一个接口供客户使用&#xff0c;具体的创建工作由工厂管…

跨境电商平台Etsy被封?那是因为你没做对这件事!

ETSY是一个在线市场和电商平台&#xff0c;专注于手工艺品、独特商品和创意艺术。它为卖家提供了一个平台来展示和销售自己的手工制品、艺术品、珠宝、家居用品、时尚配饰等各种创意产品。作为一个颇受中国商家青睐的平台&#xff0c;Etsy在账号检测方面也是不亚于亚马逊之严格…

设计模式之工厂模式(Factory)

任何可以产生对象的方法或类&#xff0c;都可以称为工厂。 下面的代码定义了Car这种交通工具: public class Car {public void go() {System.out.println("Car go wuwuwuwuw....");} }然后在main函数里面想要调用调用Car的go方法&#xff0c;就需要new一个car对象&…

音频修复增强软件iZotope RX 10 mac中文特点

iZotope RX 10 mac是一款音频修复和增强软件。 iZotope RX 10 mac主要特点 声音修复&#xff1a;iZotope RX 10可以去除不良噪音、杂音、吱吱声等&#xff0c;使音频变得更加清晰干净。 音频增强&#xff1a;iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限制器等处…

grdle 的安装与配置 、gradle和jdk版本对应关系

java与gradle对应的版本关系 Java Java Gradle需要Java版本在8到19之间。目前还不支持Java 20及更高版本。 Java 6和Java 7仍然可以用于编译&#xff0c;但已经不适合用于测试。Gradle 9.0不支持Java 6和Java 7的测试。任何完全支持的Java版本都可以用于编译或测试。 然而&…

如何使用VSCode来查看二进制文件

2023年11月6日&#xff0c;周一下午 目录 方法1&#xff1a;安装插件Binary Viewer然后用vscode打开一个二进制文件&#xff0c;并点击右上角的"HEX"方法2&#xff1a;安装插件Binary然后用vscode打开一个二进制文件&#xff0c;并点击右上角的"B" 方法1&…