泡泡的课堂小练习之那些插队的人

2023-10-24 01:30
文章标签 练习 课堂 插队 泡泡

本文主要是介绍泡泡的课堂小练习之那些插队的人,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目简述

题目背景:

随着社会整体素质的提高,插队的现象已经越来越少了。但是仍旧有一个特殊情况,需要对于某些人进行优先处理。当这些人完成了自己插队的壮举之后,队伍的形态就变得千变万化。这个时候,得知每个人在哪里就变得尤为重要的,聪明的你一定可以完成这个艰巨的任务的,加油吧!

简明题意:

你有一个长度为 n 的队伍,从左到右依次为 1~n,有 m 次插队行为,用数组 cutIn 进行表示,cutIn 的元素依次代表想要插队的人的编号,每次插队,这个人都会直接移动到队伍的最前方。你需要返回一个整数,代表这 m 次插队行为之后,有多少个人已经不在原来队伍的位置了。

示例

输入
3,[3, 2, 3]
返回值
2
说明
初始队伍为 [1, 2, 3]
3 开始插队 [3, 1, 2]
2 开始插队 [2, 3, 1]
3 开始插队 [3, 2, 1]
所以2还在原来的尾置,3和1两个人已经不在原来的位置了

代码部分

暴力解法

    /*** 计算有多少个人最终不在自己原来的位置上* @param n int整型 队伍总长* @param cutIn int整型vector 依次会插队到最前方的人的编号* @return int整型*/int countDislocation(int n, vector<int>& cutIn){//检测,当cutIn为0是表示没有人插队//当n<=1时表示只有1个人,无法插队if (cutIn.size() == 0 || n <= 1){return 0;}//给定一个v1记录1-n同时赋值vector<int> v1(n,0);for(int i=0;i<n;i++){v1[i]=i+1;}//给定一个v2复制一份v1的值用来跟对比后的v1进行比较记录vector<int> v2(v1);//遍历cutIn 同时删除v1中的该数然后将该数插入v1的开头for(int x:cutIn){int a=v1[x-1];v1.erase(v1.begin()+x-1);v1.insert(v1.begin(),a);}//用来记录不在原来的位置上的人数int count=0;//当v1和v2该位置上的数不同时,表示该人不在原来的位置上了for(int i=0;i<n;i++){if(v1[i] != v2[i])count++;}return count;}

备注:

  1. 如上代码比价容易让人理解,但缺点也很明显。内存超限
  2. 而且需要遍历同一个vector容器多次
    在这里插入图片描述

改良版

  • 通过上面的代码知道,该题目无法进行暴力解法。
  • 那么通过规律我们可以知道,只要我们找到cutIn中的最大的一个数max。
  • 那么就可以知道max-n这之间的数都没有发生过位置的改变
  • 那么就可以得到如下的代码
    int countDislocation(int n, vector<int>& cutIn) {if (cutIn.size() == 0 || n <= 1){return 0;}//记录cutIn中的最大值int max=0;//遍历cutIn,通过比较当前值与max的大小去保留最大值for(int x:cutIn){max=x>max?x:max;}//创建一个max大小的容器,max-n之间的值直接舍去vector<int> v1(max,0);//赋值for(int i=0;i<max;i++){v1[i]=i+1;}//移动for(int x:cutIn){int a=v1[x-1];v1.erase(v1.begin()+x-1);v1.insert(v1.begin(), a);}//计数int count=0;for(int i=0;i<max;i++){if(v1[i] != 1+i)count++;}return count;

备注:

  1. 改方法略微简化了移动的操作复杂度从(n减小到了max)
  2. 但当max=n时复杂度还是跟暴力破解一样
  3. 其次,该方法也存在内存超限,需要进一步修改

终版

  • 通过改良版我们舍去了不会变动的max-n的部分,那么有没有方法能进一步舍去更多的部分来达到精简的目的呢
  • 通过规律我们发现,每一个插队的人的位置,跟其最后一次插队有关。
  • 例如:2 5 1 2 那么2是在第一位,那么顺序遍历的第一个2就没有实际用处了,那么是不是可以直接跳过
  • 那么我们是否能通过反向遍历来实现呢,如果一个数第复数次出现,那么就跳过这个数。
  • 由此的到的最终版

int countDislocation(int n, vector<int>& cutIn)
{if (cutIn.size() == 0 || n <= 1){return 0;}//检测容器,用来存放第一次出现的数set<int> s1;//存放容器,用来存放所有人插完队后,插队人的容器vector<int> v1;int max=1;//反向遍历,从size()-1 至 0for(int i=cutIn.size()-1;i>=0;i--){//定义一个数,接受cutIn的值int index=cutIn[i];//如果find函数没找到该值那么会返回容器末的end()迭代器//证明未找到该数if(s1.find(index) == s1.end()){//s1容器中添加该数s1.insert(index);//将该数导入v1容器中v1.push_back(index);//比较记录最大值max=index>max?index:max;}}//定一个int变量记录不在原来位置的认输//因为假设5次插队(2,5,4,7,5).//那么max为7,队列为5,7,4,2,1,3,6//那么1,3,6是不是直接挪到后面去了根本不需要去验证//即只需要验证前面4个数是否还在原来位置上int ret=max;for(int i=0;i<v1.size();i++){//如果该数还在原来位置上,那么计数器减一if(v1[i] == i+1){ret--;}}return ret;
}
  • 该方法相较于前两个版本,极大缩减了所需要遍历的内容,也减少了创建一个队(记录所有人位置)的容器的时间。
  • 精简了对比的时间,无需进行较多无意义的对比。

这篇关于泡泡的课堂小练习之那些插队的人的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/271806

相关文章

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1(高级消息队列协议)是一种网络协议,它允许遵从该协议的客户端(Publisher或者Consumer)应用程序与遵从该协议的消息中间件代理(Broker,如RabbitMQ)进行通信。 AMQP 0-9-1模型的核心概念包括消息发布者(producers/publisher)、消息(messages)、交换机(exchanges)、

【Rust练习】12.枚举

练习题来自:https://practice-zh.course.rs/compound-types/enum.html 1 // 修复错误enum Number {Zero,One,Two,}enum Number1 {Zero = 0,One,Two,}// C语言风格的枚举定义enum Number2 {Zero = 0.0,One = 1.0,Two = 2.0,}fn m

MySql 事务练习

事务(transaction) -- 事务 transaction-- 事务是一组操作的集合,是一个不可分割的工作单位,事务会将所有的操作作为一个整体一起向系统提交或撤销请求-- 事务的操作要么同时成功,要么同时失败-- MySql的事务默认是自动提交的,当执行一个DML语句,MySql会立即自动隐式提交事务-- 常见案例:银行转账-- 逻辑:A给B转账1000:1.查询

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd

014.Python爬虫系列_解析练习

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈 PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈 Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈 优

如何快速练习键盘盲打

盲打是指在不看键盘的情况下进行打字,这样可以显著提高打字速度和效率。以下是一些练习盲打的方法: 熟悉键盘布局:首先,你需要熟悉键盘上的字母和符号的位置。可以通过键盘图或者键盘贴纸来帮助记忆。 使用在线打字练习工具:有许多在线的打字练习网站,如Typing.com、10FastFingers等,它们提供了不同难度的练习和测试。 练习基本键位:先从学习手指放在键盘上的“家位”开始,通常是左手的

anaconda3下的python编程练习-csv翻译器

相关理解和命令 一、环境配置1、conda命令2、pip命令3、python命令 二、开发思路三、开发步骤 一、环境配置 1、conda命令 镜像源配置 conda config --show channels //查看镜像源conda config --remove-key channels //删除添加源,恢复默认源#添加镜像源conda config --ad

推荐练习键盘盲打的网站

对于初学者来说,以下是一些推荐的在线打字练习网站: 打字侠:这是一个专业的在线打字练习平台,提供科学合理的课程设置和个性化学习计划,适合各个水平的用户。它还提供实时反馈和数据分析,帮助你提升打字速度和准确度。 dazidazi.com:这个网站提供了基础的打字练习,适合初学者从零开始学习打字。 Type.fun打字星球:提供了丰富的盲打课程和科学的打字课程设计,还有诗词歌赋、经典名著等多样

综合DHCP、ACL、NAT、Telnet和PPPoE进行网络设计练习

描述:企业内网和运营商网络如上图所示。 公网IP段:12.1.1.0/24。 内网IP段:192.168.1.0/24。 公网口PPPOE 拨号采用CHAP认证,用户名:admin 密码:Admin@123 财务PC 配置静态IP:192.168.1.8 R1使用模拟器中的AR201型号,作为交换路由一体机,下图的WAN口为E0/0/8口,可以在该接口下配置IP地址。 可以通过

JAVA学习-练习试用Java实现“删除有序数组中的重复项”

问题: 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 说明: 为什么返回数值是整数,但输出的答案是数组呢? 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 你可以想象内部操作如下