【C++】 —— 笔试刷题day_29

一、排序子序列

题目解析

在这里插入图片描述

一个数组的连续子序列,如果这个子序列是非递增或者非递减的;这个连续的子序列就是排序子序列。

现在给定一个数组,然后然我们判断这个子序列可以划分成多少个排序子序列。

例如:1 2 3 2 2 1 可以划分成 1 2 32 2 1两个排序子序列

算法思路

对于这道题,思路就很简单了:

暴力解法

0位置开始遍历,寻找一段连续子序列,直到这一段子序列不满足排序子序列的条件,即找到了一个排序子序列;

然后继续从上次遍历结束位置接着遍历数组,寻找下一个子序列。

贪心优化:

当我们遍历到数组中数值相同的区域时,我们要知道,要找的子序列是非递增或者非递减的;

所以这一段相等的序列,我们可以加到前面或者后面的任意序列中。

所以我们在遇到数值相等的子序列时,继续向后遍历即可。

但是这样我们会发现两个问题:

  1. 如果数组刚开始位置的数据是相等的,我们不知道这段子序列是非递增的还是非递减的;
  2. 我们在遍历过程中会用到下一个位置的值来判断是非递增还是非递减,那最后一个位置该怎么办?

对于数组开头的相等子序列,我们可以直接跳过,因为这一段相等的序列可以加到后面的子序列中;

而对于最后一个位置,如果它不能和前面序列组成一个排序子序列,那就只能让它自己组成一个排序子序列了。

在这里插入图片描述

代码实现

#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int arr[N];
int n;
int main() {cin >> n;for (int i = 0; i < n; i++)  cin >> arr[i];int ret = 0;for (int i = 0; i < n; i++) {if (i == n - 1) { //数组最后一个位置ret++;break;}if (arr[i] < arr[i + 1]) {//非递增while (i < n && arr[i] <= arr[i + 1])i++;ret++;} else if (arr[i] > arr[i + 1]) {//非递减while (i < n && arr[i] >= arr[i + 1])i++;ret++;} else {//数组开始位置的相等子序列while (i < n && arr[i] == arr[i + 1])i++;}}cout << ret << endl;return 0;
}

二、消减整数

题目解析

在这里插入图片描述

这道题给定一个正整数H,然后从1开始减,第一次减去1,之后每一次减去的数要么和上一次相等,要么是上一次的两倍;

简单来说就是:h每次减去一个数,x起始是1;之后每一h减去x或者2*xx表示上次减去的数)。

现在,最少需要几次才能将h减到0

算法思路

对于这道题,暴力解法

h每次减去x或者2*x,让它一值减,直到h减到0或者<0

简单来说就是分情况讨论:第一次减去1,之后分别考虑减去x和减去2*x的情况。

这样时间复杂度和空间复杂度都太大了;并且h每一次减也不一定会恰好等于0

贪心优化:

这道题要我们求的是将x减到0的最少次数;

那如果我们的h减去某一个数是无法减到0的,那我们就不用去考虑它了;

所以,我们现在要考虑的是,h减的过程中,减去x能否减到0;减去2*x能否减到0

这个也非常容易判断了,如果hx的整数倍,那减去x就肯定可以减到0;如果h2*x的整数倍,那减去2*x就也能减到0

现在有一个问题,如果h既是x的倍数,也是2*x的倍数, 那是减去x还是2*x呢?

很显然是减去2*X,因为我们要求的是h减到0的最小次数,那可以是减去大的数次数更小啊。

所以我们整体思路就出来了,在减的过程中,判断h2*x的倍数,如果是就减去2*x;如果不是就减去x

在这里插入图片描述

代码实现

#include <iostream>
using namespace std;
int main()
{int t;cin>>t;while(t--){int n;cin>>n;n--;//第一次减去1int ret = 1,x = 1;while(n){if(n % (2*x) == 0)x*=2;n-=x;ret++;}cout<<ret<<endl;}return 0;
}

三、最长上升子序列(二)

题目解析

在这里插入图片描述

对于这道题,给定一个数组,然后我们要找到这个数组中最长严格上升子序列的长度;

严格上升子序列:一个数组删掉其中一些数(可以不删)之后,形成的新数组它是严格上升(非递减)的。

简单来说就是:一个数组的子序列,这个子序列是严格上升的。

现在我们要找到所有上升子序列中长度最长的子序列;然后返回它的长度。

算法思路

对于这道题,一眼看起,可以说毫无思路;这该如何去找啊?

细细看来:

我们要找所有严格上升的子序列,当我们遍历到某一个位置时,我们要知道这个位置的数据和前面位置的数据是否能够形成严格上升的子序列;所以我们就要知道这个位置前面有多少个严格上升的子序列,这个位置的数据能放到哪些子序列当中去?

所以我们就要记录:当前所有的严格上升子序列,以及子序列中的元素。

那我们如何去记录所有的严格上升子序列呢?

当遍历到一个位置时:

这个位置如果是大于等于前面所有位置的,那我们可以把这个位置的元素放到任意一个子序列的后面形成一个新的子序列;

但是,我们没有必要去把这个元素放到每一个子序列的后面形成新的子序列。

加入前面有子序列11,21,2,4,当前位置数据是7,我们可以形成1,71,2,71,2,4,7三个新的子序列;但是我们可以发现长度为2的子序列有两个1,21,7,我们有必要把这两个长度一样的子序列都记录下来吗?

很显然是不需要的,我们只需要记录长度为n的子序列它最后一个元素最小的子序列即可

所以,我们只需要按长度n1,2,3...n)记录子序列即可。

那问题又来了,我们要记录子序列中的所有元素吗?

比如11,21,2,41,2,4,7,我们要记录子序列中的所有元素吗?

当然也是没有必要的;当我们遍历一个位置时,我们只需要判断这个位置的能否和前面的子序列组成新的子序列;我们不需要关心这个子序列是什么,所以我们只需要保存子序列最后一个位置的元素即可。

那现在还有一个问题:遍历一个位置时,它可以与前面子序列形成新的子序列,但是长度不是最大的怎么办?

简答来说:现在有子序列11,21,2,41,2,4,7四个子序列,现在遍历到某一个位置,这个位置的值是3

它可以和1形成1,3但是最后一个元素是3是大于1,2的最后一个元素2的,我们可以不用考虑。

它可以和1,2形成1,2,3,它最后一个元素3是小于1,2,4最后一个元素4的,我们就要修改长度为3的子序列,将4修改成3

OK啊,现在大致明白了这道题如何去解决;

但是我们要遍历一遍数组,而且还要去判断一个某一个位置是否能和前面子序列形成新的子序列,形成新的子序列是否比之前的子序列更好;那就要存放每一个长度的子序列对应的最后一个元素的值;时间复杂度那不就是O(n^2)了,题目明确要求时间复杂度是O(n log N)啊。

二分查找

所以这里我们要使用二分算法去优化查找。

当我们遍历到一个位置时,当这个位置的值是>=dp[pos](大于长度最大的子序列的最后一个位置),它可以和长度最大的子序列形成一个新的子序列,长度就是pos+1,直接新增一个位置即可(dp[pos+1] = x)。

但是如果这个位置的值是小于长度最大的子序列的最后一个位置,它可能可以和前面的某一个子序列形成新的子序列,而形成新的子序列的最后一个位置的值,一定是小于等于之前该长度的子序列最后一个位置的值的。

所以我们就要找到这个子序列;

我们按暴力查找它的时间复杂度是O(n);但是我们仔细思考可以发现,我们存放的是长度为n的子序列的最后一个位置的值,那这个数组dp是不是就是非递减的了?

所以我们就可以使用二分查找来搜索这个子序列,而我们要找的也就是>=当前位置的值的区间左端点。

在这里插入图片描述

代码实现

class Solution {public:int dp[100001];int pos = 0;int LIS(vector<int>& a) {for (auto& e : a) {if (pos == 0 || e >= dp[pos])dp[++pos] = e;else {int l = 1, r = pos;while (l < r) {int mid = l + (r - l) / 2;if (dp[mid] >= e)r = mid;elsel = mid + 1;}dp[l] = e;}}return pos;}
};

到这里,本篇文章内容就结束了。
继续加油啊!!!

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

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

相关文章

UE RPG游戏开发练手 第二十七课 普通攻击2

UE RPG游戏开发练手 第二十七课 普通攻击2 1. 创建普通攻击的蒙太奇动画 2.打开4个蒙太奇动画&#xff0c;修改插槽为FullBody,修改动画速度 3.编辑动画蓝图&#xff0c;插入FullBody插槽让普通攻击动画得以播放 4. 编辑GA_LightAttack技能蓝图

MySQL——日志

undo log(回滚日志)&#xff1a;引擎层生成的日志&#xff0c;实现了事务的原子性&#xff0c;用于事务回滚和MVCC。redo log(重做日志)&#xff1a;引擎层生成的日志&#xff0c;实现了事务的持久性&#xff0c;用于非正常关闭的数据恢复。bin log(归档日志)&#xff1a;Serve…

QML 动画控制、顺序动画与并行动画

目录 引言相关阅读基础属性说明工程结构示例代码解析示例1&#xff1a;手动控制动画&#xff08;ControlledAnimation.qml&#xff09;示例2&#xff1a;顺序动画&#xff08;SequentialAnimationDemo.qml&#xff09;示例3&#xff1a;并行动画&#xff08;ParallelAnimationD…

PowerShell 实现 conda 懒加载

问题 执行命令conda init powershell会在 profile.ps1中添加conda初始化的命令。 即使用户不需要用到conda&#xff0c;也会初始化conda环境&#xff0c;拖慢PowerShell的启动速度。 解决方案 本文展示了如何实现conda的懒加载&#xff0c;默认不加载conda环境&#xff0c;只…

R语言学习--Day03--数据清洗技巧

在一般情况下&#xff0c;我们都是在数据分析的需求前提下去选择使用R语言。而实际上&#xff0c;数据分析里&#xff0c;百分之八十的工作&#xff0c;都是在数据清洗。并不只是我们平时会提到的异常值处理或者是整合格式&#xff0c;更多会涉及到将各种各样的数据整合&#x…

谷歌地图代理 | 使用 HTML 和矢量模式 API 更轻松地创建 Web 地图

在过去的一年里&#xff0c;谷歌对 Maps JavaScript API 进行了两项重要更新&#xff0c;以便更轻松地采用我们最新、最好的地图&#xff1a;HTML 地图和矢量模式 API。今天谷歌地图亚太区最大代理商之一的 Cloud Ace云一 为大家介绍一下更新的具体内容。 联系我们 - Cloud Ac…

WL-G4048 Multi-Port PCIe 4.0 Switch

系列文章目录 文章目录 系列文章目录《WL-G4048 Multi-Port PCIe 4.0 Switch数据手册》总结一、芯片介绍二、芯片规格介绍&#xff08;一&#xff09;功能指标&#xff08;二&#xff09;管理调试和监控&#xff08;三&#xff09;参考时钟&#xff08;四&#xff09;系统复位 …

召回11:地理位置召回、作者召回、缓存召回

GeoHash 召回 属于地理位置召回&#xff0c;用户可能对附近发生的事情感兴趣。GeoHash 是一种对经纬度的编码&#xff0c;地图上每个单位矩形的 GeoHash 的前几位是相同的&#xff0c;GeoHash 编码截取前几位后&#xff0c;将相同编码发布的内容按时间顺序&#xff08;先是时间…

高效批量合并Word文档的工具介绍

软件介绍 本文介绍一款专门用于批量合并Word文档的工具&#xff0c;名为批量合并word工具。 使用方法与特点 如果需要将多个Word文档合并到一个Word文档中&#xff0c;就可以使用这款工具。使用前&#xff0c;需把要合并的Word文档都放在名为“word”的文件夹下。 该软件没有…

机器学习入门之KNN算法和交叉验证与超参数搜索(三)

机器学习入门之KNN算法和交叉验证与超参数搜索&#xff08;三&#xff09; 文章目录 机器学习入门之KNN算法和交叉验证与超参数搜索&#xff08;三&#xff09;一、KNN算法-分类1. 样本距离判断明可夫斯基距离 2. KNN 算法原理3. KNN 的缺点4. KNN 的 API5. 使用 sklearn 实现 …

小刚说C语言刷题—1700请输出所有的2位数中,含有数字2的整数

1.题目描述 请输出所有的 2 位数中&#xff0c;含有数字 2 的整数有哪些&#xff0c;每行 1个&#xff0c;按照由小到大输出。 比如&#xff1a; 12、20、21、22、23… 都是含有数字 2的整数。 输入 无 输出 按题意要求由小到大输出符合条件的整数&#xff0c;每行 1 个。…

在MYSQL中导入cookbook.sql文件

参考资料&#xff1a; GitHub 项目&#xff1a;svetasmirnova/mysqlcookbook CSDN 博客&#xff1a;https://blog.csdn.net/u011868279/category_11645577.html 建库&#xff1a; mysql> use mysql Reading table information for completion of table and column names …

Scrapy框架下地图爬虫的进度监控与优化策略

1. 引言 在互联网数据采集领域&#xff0c;地图数据爬取是一项常见但具有挑战性的任务。由于地图数据通常具有复杂的结构&#xff08;如POI点、路径信息、动态加载等&#xff09;&#xff0c;使用传统的爬虫技术可能会遇到效率低下、反爬策略限制、任务进度难以监控等问题。 …

【Win32 API】 lstrcmpA()

作用 比较两个字符字符串&#xff08;比较区分大小写&#xff09;。 lstrcmp 函数通过从第一个字符开始检查&#xff0c;若相等&#xff0c;则检查下一个&#xff0c;直到找到不相等或到达字符串的末尾。 函数 int lstrcmpA(LPCSTR lpString1, LPCSTR lpString2); 参数 lpStr…

代码随想录60期day38

2维背包 #include<bits/stdc.h> using namespace std;int main(){int n,bagweight;cin>>n>>bagweight;vector<int>weight(n,0);vector<int>value(n,0);for(int i 0 ; i <n;i){cin>>weight[i];}for(int j 0;j<n;j){cin>>val…

[模型部署] 1. 模型导出

&#x1f44b; 你好&#xff01;这里有实用干货与深度分享✨✨ 若有帮助&#xff0c;欢迎&#xff1a;​ &#x1f44d; 点赞 | ⭐ 收藏 | &#x1f4ac; 评论 | ➕ 关注 &#xff0c;解锁更多精彩&#xff01;​ &#x1f4c1; 收藏专栏即可第一时间获取最新推送&#x1f514;…

mac的Cli为什么输入python3才有用python --version显示无效,pyenv入门笔记,如何查看mac自带的标准库模块

根据你的终端输出&#xff0c;可以得出以下结论&#xff1a; 1. 你的 Mac 当前只有一个 Python 版本 系统默认的 Python 3 位于 /usr/bin/python3&#xff08;这是 macOS 自带的 Python&#xff09;通过 which python3 确认当前使用的就是系统自带的 Pythonbrew list python …

Java注解详解:从入门到实战应用篇

1. 引言 Java注解&#xff08;Annotation&#xff09;是JDK 5.0引入的一种元数据机制&#xff0c;用于为代码提供附加信息。它广泛应用于框架开发、代码生成、编译检查等领域。本文将从基础到实战&#xff0c;全面解析Java注解的核心概念和使用场景。 2. 注解基础概念 2.1 什…

前端方法的总结及记录

个人简介 &#x1f468;‍&#x1f4bb;‍个人主页&#xff1a; 魔术师 &#x1f4d6;学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全栈发展 &#x1f6b4;个人状态&#xff1a; 研发工程师&#xff0c;现效力于政务服务网事业 &#x1f1e8;&#x1f1f3;人生格言&…

组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果

组件导航 (Navigation)flutter项目搭建 接上一章flutter项目的环境变量配置并运行flutter 1.flutter创建项目并运行 flutter create fluter_hmrouter 进入ohos目录打开编辑器先自动签名 编译项目-生成签名包 flutter build hap --debug 运行项目 HMRouter搭建安装 1.安…