基数排序及利用数组简化解题

红豆不堪看,满眼相思泪

在这里插入图片描述

 本文主要是帮助大家熟练掌握利用数组进行有关判断的题目,看完本文后在之后的刷题中都可以利用这种思想,当然举例中的题目利用该种方法可能不是最优解,但绝对是你看到题目不用思考太多就可以做出来的方法,当然我也会介绍所列题目的其他方法以供大家思考,话不多说,进入正题。

基数排序
思想:已经给定一个数组,数组中就是我们需要排序的数列,再开辟一个数组,该数组的个数n为要排序的数中最大的数+1且全部初始化为0,根据需要排序数组中的数,找到新开辟的数组中该数的下标的位置,将该位置的数++。
例如
在这里插入图片描述
 逻辑很简单,直接谈如何优化,一眼看出,某种情况下这种思路排序开的空间太大了,就比如要排序的数全部在1000~2000之间的数,我们从0开始开空间,那么前1000的空间就是白开了,造成很大的空间浪费。
我们可以先进行遍历,找到要排序数组中最大值和最小值,两者作差再加1,就是我们需要开的空间。
代码如下

//基数排序
void CountSort(int* a, int n)
{int min = a[0], max = a[0];for (int i = 0; i < n; i++){if (a[i] < min){min = a[i];}if (a[i] > max){max = a[i];}}int range = max - min + 1;int* count = (int*)malloc(sizeof(int) * range);if (count == NULL){perror("malloc fail");return;}memset(count, 0, sizeof(int) * range);//统计数据出现的次数for (int i = 0; i < n; i++){count[a[i] - min]++;//开的空间是减去min的,所以排序数组中的数在存储时也要减去min。}int j = 0;for (int i = 0; i < range; i++){while (count[i]--){a[j++] = i + min;//该位置的数出现几次,就统计出几次}}
}

基数排序总结

  1. 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限。如果是小数呢?你就无法用下标进行存储了。
  2. 时间复杂度:O(N(范围))
  3. 空间复杂度:O(N)

OK,介绍5个用到该思想的题目,帮大家掌握住这种做题方法
1,错误的集合
在这里插入图片描述
这道题的解法很多
 思路一:最容易想到的就是先排序,然后就可以很轻易的找到消失的数字,而且我们已经知道了包含1到n,可以直接求和减去出现差错的数组中的所有元素,例如将5复制成了7,减完之后结果为-2,那么重复的数就是5加上2为7。
 思路二:直接利用基数排序的思想。重新开一个数组(初始化全部为0),不用排序,直接用所给集合里面的所有数对应的下标位置加加,当然,如果没出现某个数,那么新开数组这个位置的数就是0,重复的就是1。
代码如下

int* findErrorNums(int* nums, int numsSize, int* returnSize)
{int *array1,*array2,i;array1=(int*)calloc(numsSize,sizeof(int));array2=(int*)malloc(sizeof(int)*2);for(i=0;i<numsSize;i++){array1[nums[i]-1]+=1;}for(i=0;i<numsSize;i++){if(array1[i]==2)array2[0]=i+1;else if(array1[i]==0)array2[1]=i+1;}*returnSize=2;return array2;    
}

 逻辑清晰,时间复杂度为O(N),空间复杂度为O(N)。当然也可以加一个判断,当已经找到两个数字后直接跳出循环,减少循环次数。


2,字符个数统计
在这里插入图片描述

 同样还是找一段区间中是否存在某个数,或者某个数出现的次数,字符也是整形,可以利用字符表示的整形还是同样依照上边的那种思路进行解题只需要强制转化,其他思路全部相同。
代码如下

#include <stdio.h>
int main() {int i = 0;int count = 0;char arr1[500];int arr[127] = { 0 };scanf("%s", arr1);while (arr1[i] != '\0'){arr[(int)arr1[i]] = 1;i++;}for (int j = 0; j < 127; j++){if (arr[j] == 1){count++;}}printf("%d", count);return 0;
}

 同样,只要使用这种思路时间复杂度一般都是O(N),由于题目都说了,范围在0~127之间,用这种思路多爽啊。


3,多数元素
在这里插入图片描述
 给定数组,找到数组中出现次数大于numsSize/2的数,我们还可以使用这种方法,但是这道题使用这种方法跑不过,虽然已经知道了我们要开多少的空间(时间复杂度为O(1)),但是数组中数的最大值和最小值相差2*10^9,这个数字太大了,意味着我们要开的空间也是非常大的,这道题要想用时间复杂度为O(N),用这种方法是跑不过的。但是可以骗骗分,正如上边所说,介绍的是一种思路而已,当然还会给出另外的解法。
利用数组下标做法代码如下啊

int majorityElement(int* nums, int numsSize) {int min = nums[0], max = nums[0];for (int i = 0; i < numsSize; i++){if (nums[i] < min){min = nums[i];}if (nums[i] > max){max = nums[i];}}int range=max-min+1;int*arr=(int*)malloc(sizeof(int)*(range));for (int k = 0; k < range; k++){arr[k] = 0;}for (int i = 0; i < numsSize; i++){arr[nums[i] - min]++;}for(int j=0;j<range;j++){if(arr[j]>numsSize/2){return j+min;}}return -1;
}

 仔细观察可以发现和前边基数排序的方法手段如此相像,只不过在存储完成后要判断或得到的东西不同而已。
用这个代码跑的话,是通过不了的,因为某些用例专门针对。
在这里插入图片描述
可以发现,过了大部分用例
在这里插入图片描述
 剩下的估计都含有这两个数字,不知道优化能不能成功,也不想费那么多事,如果用例中数组内的数字差别没有这么大,那么这种解法的时间复杂度为O(N),空间复杂度为O(1)。

OK,不能就这么摆着一个不能通过的方法在这里

谈一谈投票法(很巧妙)
 利用该数组中多数元素的次数绝对大于numsSIze/2这一特性,所以用不同的元素消去相同的对象,那么身下到最后的绝对是相同元素,即我们要找的多数元素。
在这里插入图片描述
代码如下

int majorityElement(int*nums,int numsSize)
{int candidate=nums[0];int flag=1;for(int i=1;i<numsSize;i++){if(nums[i]==candidate){flag++;}else{flag--;if(flag<0){candidate=nums[i];flag=1;}}}return candidate;
}

4,找到所有数组中消失的数据
在这里插入图片描述

 同样,这道题也是与数组中某个数字是否存在或者某个数字出现了几次的问题,利用同样的思路,不需要排序即可找出,且时间复杂度为O(N),但是我们开了额外的空间,至于进阶的写法,先放一放。
代码如下

/*** Note: The returned array must be malloced, assume caller calls free().*/
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){int k=0;int*arr=(int*)malloc(sizeof(int)*(numsSize));int*ret=(int*)malloc(sizeof(int)*(numsSize));//memset(arr,0,(sizeof(int)*(numsSize+1)));for(int l=0;l<numsSize;l++){arr[l]=0;}for(int i=0;i<numsSize;i++){arr[nums[i]-1]++;}for(int j=0;j<numsSize;j++){if(arr[j]==0){ret[k++]=j+1;//*returnSize++;}}*returnSize=k;return ret;
}

总结:判断数组中某数(尤其是无序)出现的个数(判断有没有出现就是出现个数是不是0嘛),就可以使用这种方法,和基数排序原理一样,空间换时间,开空间时一定要的。
 结束啦结束啦,希望你有所收获,这就是我创作的最大动力。

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

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

相关文章

容器有挂载目录的时候,容器反向生成为镜像,挂载的内容不会保留。只有实打实拷贝进容器的反向生成镜像才会保留。

无容器目录挂载 1、也就是说宿主机未与容器进行路径映射&#xff0c;故我们可以直接使用指令: docker commit 容器名称/容器ID 像名:标签号&#xff0c;把容器保存为镜像; (其中镜像名和标签号是我们随机取的&#xff0c;新镜像名以及我们的标签号!) 2、我们在不能判断容器与宿…

mysql mybatis分页查询 大数据量 非常慢

查阅了很多博客和资料&#xff0c;这篇文章以思路为准&#xff0c;详细代码不细说&#xff0c;都是非常简单的方法&#xff0c;一看就明白。具体实现稍微百度一下就能出来。仅供参考。 如题&#xff1a;单表数据已经达到4千万条数据&#xff0c;通过mybatis的分页查询效率非常低…

Netfilter中的NAT

目录 前瞻 SNAT和DNAT SNAT DNAT 实验 前瞻 NAT: &#xff08;network address translation&#xff09;&#xff0c;支持PREROUTING&#xff0c;INPUT&#xff0c;OUTPUT&#xff0c;POSTROUTING四个链 NAT分为SNAT和DNAT SNAT&#xff1a;支持POSTROUTING, INPUT&…

ant design vue3 处理 ant-card-head ant-tabs靠左边对齐之has选择器不生效

火狐浏览器是不支持has的。 解决方法&#xff1a;通过position来解决。

Spring Cloud 配置 Nacos

一&#xff0c;下载Nacos 下载地址&#xff1a;https://github.com/alibaba/nacos/releases 二&#xff0c;启动Nacos 安装Nacos的bin目录下&#xff0c; 执行&#xff1a;startup.cmd -m standalone 然后打开上图红框的地址 三&#xff0c;配置服务 1 配置Nacos 创建命名…

「Bomkus 博士的试炼」排行榜规则更新

亲爱的玩家们 为了回应我们从社区收到的宝贵反馈&#xff0c;我们希望与大家分享我们为防止在「Bomkus 博士的试炼」排行榜中作弊而采取的措施的最新进展&#xff0c;并就这一主题提供更多说明。 除了在活动开始前采取的反作弊措施外&#xff0c;我们还根据观察到的和报告的行为…

python之pyqt专栏9-鼠标事件

目录 需求 UI界面 代码实现 代码解析&#xff1a; Label初始化设置 重写鼠标按下事件 重写鼠标释放事件 重写鼠标移动事件 运行结果 需求 当鼠标进入窗口时&#xff0c;点击鼠标左键&#xff0c;出现一个label并在显示光标在窗口的坐标&#xff1b;按住左键不释放拖动…

AntDB“超融合+流式实时数仓”——打造分布式数据库新纪元

&#xff08;一&#xff09; 前言 据统计&#xff0c;在信息化时代的今天&#xff0c;人们一天所接触到的信息量&#xff0c;是古人一辈子所能接收到的信息量的总和。当今社会中除了信息量“多”以外&#xff0c;人们对信息处理的“效率”和“速度”的要求也越来越高。譬如&a…

网络基础--win10双网卡设置成访问不同的网络

1、背景 我日常中大部分时间都是使用外网的网卡进行办公&#xff0c;只有在连接公司服务器时才需要使用内网。由于我的电脑存在两张网卡&#xff0c;分别用于连接不同的网络&#xff08;常见情况是一张访问公司内网&#xff0c;一张访问公司外网&#xff09;&#xff0c;但是在…

Small Data Transmission(一) overview

在R16之前,RRC Inactive 不支持数据传输,UE在RRC inactive状态有data要传输时,就要通过RRC resume过程,转换到RRC connected mode才能进行数据传输。 有时候UE要传输的数据包可能会很小,且发送频率也很低,如果每次发送数据都要进行上述过程,就会增加不必要的功耗和信令…

力扣日记11.28-【二叉树篇】二叉树的最小深度

力扣日记&#xff1a;【二叉树篇】二叉树的最小深度 日期&#xff1a;2023.11.28 参考&#xff1a;代码随想录、力扣 111. 二叉树的最小深度 题目描述 难度&#xff1a;简单 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点…

TDA4VM EVM开发板调试笔记

文章目录 1. 前言2. 官网资料导读3. 安装 Linux SDK4. 制作SD 启动卡5. 验证启动1. 前言 TDA4作为一般经典的车规级SOC芯片,基于它的低阶智驾方案目前成为各家智驾方案公司的量产首选,这也使得基于TDA4的开发需求陡增,开发和使用TDA4既要熟悉Linux驱应用开发,还要熟悉传统…

《opencv实用探索·五》opencv小白也能看懂的图像腐蚀

1、图像腐蚀原理简单理解&#xff1a; 腐蚀是形态学最基本的操作&#xff0c;都是针对白色部分&#xff08;高亮部分&#xff09;而言的。即原图像中高亮部分被蚕食&#xff0c;得到比原图更小的区域。 2、图像腐蚀的作用&#xff1a; &#xff08;1&#xff09;去掉毛刺&…

如何安装鸿蒙Harmony 4.0低版API9三方库

比如我要用下拉刷新三方库pulltorefresh 安装命令如下 ohpm install ohos/pulltorefresh 安装完后然后运行Demo报错,说没有isAtEnd方法 然后查看pulltorefresh 最新版2.0.4对应Harmony API10,然而我的手机是API9,所以必须找到API9的库&#xff0c;然后查看2.0.1是还是API9 所…

测试与管理 Quota

用myquota1创建一个大的文件测试 理论猜想&#xff1a;超过soft可以&#xff0c;但是超过hard就不行了&#xff0c;最大值就是hard&#xff0c;如果超过soft&#xff0c;过了17天不处理&#xff0c;最后限制值会被强制设置成soft。修改设置成hard值 切换测试用户&#xff0c;m…

对话汪源:数智时代为企业构建新的竞争力,和网易数帆的“为与不为”

CodeWave在内的诸多“主演”正在重新演绎网易数帆&#xff0c;在网易数帆的新故事里&#xff0c;做专业、底层、核心的工具&#xff0c;是其成长至今最核心的底色。 作者|斗斗 编辑|皮爷 出品|产业家 “我希望在中间层能构建一个好的生态。”网易汪源的这句话&#xff0c;让…

如何使用Qchan搭建更好保护个人隐私的本地图床并在公网可访问

文章目录 前言1. Qchan网站搭建1.1 Qchan下载和安装1.2 Qchan网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar云端设置2.2 Cpolar本地设置 3. 公网访问测试总结 前言 图床作为云存储的一项重要应用场景&#xff0c;在大量开发人员的努力下&#xff0c;已经开发出大…

如何让你的 Jmeter+Ant 测试报告更具吸引力?

引言 想象一下&#xff0c;你辛苦搭建了一个复杂的网站&#xff0c;投入了大量的时间和精力进行开发和测试。当你终于完成了测试并准备生成测试报告时&#xff0c;你可能会发现这个过程相当乏味&#xff0c;而对于其他人来说&#xff0c;它可能也不那么吸引人。 但是&#xf…

大语言模型新升级:亚马逊云科技2023芯片创新日

在这个充满活力的2023年芯片创新日&#xff0c;Amazon EC2 的副总裁 Dave Brown 与观众分享了他与 EC2 的15年漫长旅程。他的眼中闪烁着对技术的热情&#xff0c;他描述了自己如何与一个才华横溢的团队合作&#xff0c;在这大语言模型与生成式AI的元年中致力于为客户提供最佳的…

ELK+filebeat+kafka

无需创建logstash的端口&#xff0c;直接创建topic 远程收集mysql和httpd的日志 &#xff08;一&#xff09;安装nginx和mysql服务 1、打开mysql的日志功能 2、创建日志&#xff08;创库、创表、添加数据&#xff09; &#xff08;1&#xff09;mysql服务器上安装http system…