【2018年数据结构真题】

方法一

给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4。要求:

  1. 给出算法的基本设计思想。

  2. 根据设计思想,采用C或C++语言描述算法,关键之 处给出注释。

  3. 说明你所设计算法的时间复杂度和空间复杂度。

读完题目先找关键词,这里可以直接提取这样几个关键词

  • 使用数组,求未出现的最小正整数
  • 看到数组,是不是想到是否有序
  • 时间+空间尽可能高效

暴力解:快速排序,然后扫描一遍数组

先对数组A快速排序得到升序序列,然后遍历数组找到第一个未出现的最小正整数。

void Qsort(int A[], L, R){      //a数组保存数据,L和R是边界
    if (L>=R) return;      //当前区间元素个数<=1则退出
    int key, i=L, j=R;     //i和j是左右两个数组下标移动
    
//把a数组中随机一个元素和A[L]交换,快排优化,使得基准值的选取随机

    key=A[L]; //key作为枢值参与比较while (i<j){
        while (i<j && A[j]>key) j--;
        while (i<j && A[i]<=key) i++;
        if (i<j) swap(A[i], A[j]); //交换A[i]和A[j]
    }
    swap(A[L], A[i]);
    Qsort(A, L, i-1); //递归处理左区间
    Qsort(A, i+1, R); //递归处理右区间
 }

void ans(int A[], n){ //算法代码
    Qsort(A, 0, n-1);
    int i=0;
    while (i<n && A[i]<=0) 
        i++;
    if (i==n){ //数组A全是非正数
        cout<<1;//输出1 
        return;
    }
    /*到这里,A[i]是数组中最小的正数*/ 
    
    int t=1;//t从1开始
    for (int j=i; j<n; j++){ 
        if (t==A[j])
            continue; 
        if (t+1==A[j])
            t++;
        else{ //t+1空缺
            cout<<t+1; //输出j-i+1 
            return;
    }
    cout<<t+1;//遍历完数组,输出t+1
    }
}

方法二

解析:

思想借鉴到了 Counting sort 中的方法。既然不能用额外空间,那就只有利用
数组本身,跟 Counting sort 一样,利用数组的 index 来作为数字本身的索引,把正
数按照递增顺序依次放到数组中。即让 A[0]=1, A[1]=2, A[2]=3, … , 这样一来,
最后如果哪个数组元素违反了 A[i]=i+1 即说明 i+1 就是我们要求的第一个缺失的正
数。对于那些不在范围内的数字,我们可以直接跳过,比如说负数,0,或者超过数组
长度的正数,这些都不会是我们的答案。

思路:

交换数组元素,使得数组中第 i 位存放数值(i+1)。最后遍历数组,寻找第一
个不符合此要求的元素,返回其下标。整个过程需要遍历两次数组,复杂度为 O(n)。
下图以题目中给出的第二个例子为例,讲解操作过程。

image.png

public int firstMissingPositive(int []A){
    if(A==null||A.length==0)
    {
        return 1;
    }
    for(int i=0;i<A.length;i++)
    {
        if(A[i]<=A.length && A[i]>0 && A[A[i]-1]!=A[i])
        {
            int temp = A[A[i]-1];
            A[A[i]-1] = A[i];
            A[i] = temp;
            i--;
        }
    }
    for(int i=0;i<A.length;i++)
    {
        it(A[i]!=i+1)
            return i+1;
    }
    return A.length+1;
}

实现中还需要注意一个细节,就是如果当前的数字所对应的下标已经是对应数字了,
那么我们也需要跳过,因为那个位置的数字已经满足要求了,否则会出现一直来回交
换的死循环。这样一来我们只需要扫描数组两遍,时间复杂度是 O(2*n)=O(n),而且
利用数组本身空间,只需要一个额外变量,所以空间复杂度是 O(1)。

补充

Counting sort 基本思想

对于给定的输入序列中的每一个元素 x,确定该序列中值小于 x 的元素的个数 。一
旦有了这个信息,就可以将 x 直接存放到最终的输出序列的正确位置上。它创建一个
长度为这个数据范围的数组 C,C 中每个元素记录要排序数组中对应记录的出现个
数。

下面以示例来说明这个算法:

假设要排序的数组为 A = {1,0,3,1,0,1,1}这里最大值为 3,最小值为 0,那么我们
创建一个数组 C,长度为 4。

然后一趟扫描数组 A,得到 A 中各个元素的总数,并保持到数组 C 的对应单元中。比如 0 的出现次数为 2 次,则 C[0] = 2;1 的出现次数为4 次,则 C[1] = 4。由于 C 是以 A 的元素为下标的,所以这样一做,A 中的元素在 C中自然就成为有序的了,这里我们可以知道 顺序为 0,1,3 (2 的计数为 0)然后我们把这个在 C 中的记录按每个元素的计数展开到输出数组 B 中,排序就完成了。

也就是 B[0] 到 B[1] 为 0 B[2] 到 B[5] 为 1 这样依此类推。
这种排序算法,依靠一个辅助数组来实现,不基于比较,算法复杂度为 O(n) ,但由
于要一个辅助数组 C,所以空间复杂度要大一些,由于计算机的内存有限,所以这种
算法不适合范围很大的数的排序。

上述为计数排序算法的经典解法,不过这个解法并不是最优的,因为空间复杂度还应
该可以优化,我们完全可以不要那个输出的数组 B,直接对 C 进行排序。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计循环队列(详解)

呀哈喽&#xff0c;我是结衣 今天给大家带来的内容如标题所述&#xff0c;我们来设计环形队列&#xff0c;虽然队列没有讲&#xff0c;但是我就是想讲啊。那么环形队列现在开始。 队列的属性 在设计环形队列前&#xff0c;我们先要了解队列的特点&#xff08;先进先出&#x…

TypeScript枚举

1、数字枚举 enum Direction {Up,Down,Left,Right, } var Direction; (function (Direction) {Direction[Direction["Up"] 0] "Up";Direction[Direction["Down"] 1] "Down";Direction[Direction["Left"] 2] "L…

CTF靶场搭建及Web赛题制作与终端docker环境部署

♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ 写在前面 ╔═══════════════════════════════════════════════════…

Servlet---HttpServlet、HttpServletRequest、HttpServletResponseAPI详解

文章目录 HttpServlet基础方法doXXX方法Servlet的生命周期 HttpServletRequest获取请求中的信息获取请求传递的参数获取 query string 里的数据获取form表单里的数据获取JSON里的数据如何解析JSON格式获取数据返回数据 HttpServletResponse设置响应的Header设置不同的状态码设置…

羊大师教你如何有效解决工作中的挑战与压力?

在现代社会&#xff0c;工作问题一直是许多人头疼的难题。无论是从工作压力到职业发展&#xff0c;工作问题不仅会影响个人的心理健康&#xff0c;还可能对整个工作团队的效率和和谐产生负面影响。因此&#xff0c;如何有效解决工作问题成为了每个职场人士都需要面对的挑战。 …

性能测试:系统架构性能优化思路

今天谈下业务系统性能问题分析诊断和性能优化方面的内容。这篇文章重点还是谈已经上线的业务系统后续出现性能问题后的问题诊断和优化重点。 系统性能问题分析流程 我们首先来分析下如果一个业务系统上线前没有性能问题&#xff0c;而在上线后出现了比较严重的性能问题&#x…

sonar对webgoat进行静态扫描

安装sonar并配置 docker安装sonarqube&#xff0c;sonarQube静态代码扫描 - Joson6350 - 博客园 (cnblogs.com) 对webgoat进行sonar扫描 扫描结果 bugs Change this condition so that it does not always evaluate to "false" 意思是这里的else if语句不会执行…

如何训练专属的OCR文字识别模型

1. 背景 在10月24日程序员节&#xff0c;公司决定向每位技术人员发放购物实体卡以示庆祝。然而&#xff0c;手动输入实体卡上的一大串卡密可能是一项繁琐且不那么智能的任务&#xff1b;同时&#xff0c;线上用户在绑定购物卡的时候&#xff0c;同样也是需要手动输入。 基于以…

城市易涝点监测,内涝积水监测仪的作用

近些年城市内涝问题格外突出&#xff0c;市民心中总在担心是不是哪一天自己的家园因为内涝&#xff0c;从而短时间内无法正常生活。并且内涝过后的淤泥可能堆积到路边或者居民住宅区等地&#xff0c;这会影响城市生态环境和公共卫生。 内涝积水监测仪为解决城市内涝问题提供了更…

专业远程控制如何塑造安全体系?向日葵“全流程安全闭环”解析

安全是远程控制的重中之重&#xff0c;作为国民级远程控制品牌&#xff0c;向日葵远程控制就极为注重安全远控服务的塑造。近期向日葵发布了以安全和核心的新版“向日葵15”以及同步发布《贝锐向日葵远控安全标准白皮书》&#xff08;下简称《白皮书》&#xff09;&#xff0c;…

Redis性能压测、监控工具及优化方案

Redis是一款高性能的开源缓存数据库&#xff0c;但是在实际应用中&#xff0c;我们需要对Redis进行性能压测、监控以及优化&#xff0c;以确保其稳定性和高可用性。本文将介绍Redis性能压测、监控工具及优化方案。 01 Redis性能压测 常用的Redis性能压测工具有&#xff1a; …

git的实验:cherry-pick,github对比代码的两种方式

某个commit&#xff0c;比如 c1&#xff0c;&#xff0c;最早是在a分支做的&#xff0c;当被cherry-pick到b分之后&#xff0c;还是一样的revision吗&#xff1f; 实验1&#xff1a;c1被cherry-pick到别的分支后&#xff0c;revision不变对吗&#xff1f;&#xff08;答案是变…

在矩池云使用安装AgentTuning

AgentTuning 是清华大学和智谱AI共同推出的 AI Agent方案。 AgentTuning可以令LLM具备更强大的泛化能力&#xff0c;而且同时保持其通用语言能力&#xff0c;项目中包含的AgentInstruct 数据集和 AgentLM 模型均已开源。 项目地址&#xff1a;https://github.com/THUDM/Agent…

免费图书教材配套资料:Spark大数据技术与应用(第2版)

《Spark大数据技术与应用&#xff08;第2版&#xff09;》课程内容全面介绍了Spark大数据技术的相关知识&#xff0c;内容包含包括Spark概述、Scala基础、Spark编程、Spark编程进阶、Spark SQL结构化数据文件处理、Spark Streaming实时计算框架、Spark GraphX图计算框架、Spark…

OSG文字-HUD显示汉字示例(3)

显示文字是一种非常实用的技术&#xff0c;可以用来把一些重要的文字始终显示在屏幕上。HUD的全称是HeadsUpDisplay&#xff0c;即抬头显示&#xff0c;这种技术最早应用在军事战斗机上。 创建HUD显示的基本步骤如下: <1> 创建一个osg::Camera对象&#xff0c;设置视图、…

接口自动化中cookies的处理技术

一&#xff0c;理论知识 为什么有cookie和session&#xff1f; 因为http协议是一种无状态的协议&#xff0c;即每次服务端接受到客户端的请求时都时一个全新的请求&#xff0c;服务器并不知道客户端的请求记录&#xff0c;session和cookie主要目的就是弥补http的无状态特性 …

shell脚本之循环语句(for、while、untli)

循环语句&#xff1a; 一定要有跳出循环条件 循环条件&#xff1a; 1.已知循环的次数&#xff08;新来十个人&#xff0c;就要新建十个账号 2.未知循环的次数&#xff0c;但是要有跳出循环条件&#xff08;对象生气&#xff0c;要道歉到原谅为止&#xff09; for&#xff…

AI的未来!Salesforce发布2024年全球科技的重要预测

Salesforce领导者处于影响企业的最新趋势、技术和挑战的前线&#xff0c;通过市场分析、客户对话等方面带来专业知识和洞察力。毫无疑问&#xff0c;人工智能是本年度的最热话题&#xff0c;Salesforce关于技术和人工智能的预测值得关注。 生成式AI改变商业未来的方式 01 生…

Centos7安装Cesi(Supervisor集中管理工具)

Background CeSi 是 Supervisor 官方推荐的集中化管理 Supervisor 实例的 Web UI&#xff0c;该工具是用 Python 编写&#xff0c;基于 Flask Web 框架 。Superviosr 自带的 Web UI 不支持跨机器管理Supervisor 进程&#xff0c;功能比较简单&#xff0c;通过 CeSi 可以集中管理…