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

红豆不堪看,满眼相思泪

在这里插入图片描述

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

基数排序
思想:已经给定一个数组,数组中就是我们需要排序的数列,再开辟一个数组,该数组的个数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.hqwc.cn/news/234332.html

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

相关文章

实验8配置工具

一、实验目的 1. 掌握UML中建模工具——部署图&#xff0c;用于显示系统中软件和硬件的物理架构。 2. 掌握应用Visio等业界常用的建模工具的基本使用方法和基本绘图操作&#xff0c;选择一种并熟练使用&#xff0c;会使用该工具针对具体问题建立分析模型。 二、实验内容与步骤…

桥接设计模式

package com.jmj.pattern.bridge;/*** 视频文件(实现化角色)*/ public interface VideoFile {void decode(String fileName); }package com.jmj.pattern.bridge;public class RmvFile implements VideoFile{Overridepublic void decode(String fileName) {System.out.println(&…

米贸搜|如何用Facebook为eBay实现引流?

要利用Facebook为eBay实现引流&#xff0c;可以尝试以下方法&#xff1a; 创建专页或社群&#xff1a;在Facebook上创建一个专页或社群&#xff0c;专注于你在eBay上销售的产品或相关主题。确保专页或社群的名称和描述清楚地表明与eBay有关。 定期发布内容&#xff1a;在Face…

彻底解决A JNI error has occurred, please check your installation and try again

报错信息 A JNI error has occurred, please check your installation and try again Exception in thread "main" java.lang.UnsupportedClassVersionError: org/springframework/boot/loader/JarLauncher has been compiled by a more recent version of the Java…

Sourcepawn 脚本入门(一)准备

&#x1f34e;Sourcepawn 脚本入门(一)准备 1.Sourcepawn是什么? Sourcepawn是SourceMod团队开发的基于source-sdk的服务器插件开发的一种脚本语言。 SourceMod: Half-Life 2 Scripting 它适用于大部分起源引擎的游戏&#xff0c;多见于L4D&#xff0c;CSS,CSGO&#xff0c; …

C盘爆红 教你如何快速释放空间

目录 问题描述&#xff1a; C盘爆红 快速清理空间&#xff1a; 1.找到设置 2.选择系统 3.打开存储 4.进入清理建议 5.选择以前的Windows安装文件 6.点击清理 7.至此清理完成 问题描述&#xff1a; C盘爆红 快速清理空间&#xff1a; 1.找到设置 2.选择系统 3.打开存储 4.进入清…

vue2全局混入正确使用场景和错误场景示例

全局混入在 Vue.js 中的使用场景需要谨慎考虑&#xff0c;因为它会影响所有组件。以下是一些正确和错误的使用场景的例子&#xff1a; 正确的使用场景&#xff1a; 全局工具方法&#xff1a; // 正确的使用场景 Vue.mixin({methods: {$formatDate: function (date) {// 格式化…

Android的启动模式

Android的四种启动模式&#xff1a;standard、singleTop、singleTask和singleInstance。 1.standard Android默认的启动模式是standard&#xff0c;每启动一个Activity&#xff0c;它都会在返回栈中入栈&#xff0c;并处于栈顶&#xff0c;不管这个返回栈是否存在这个activit…

C语言——指针(三)

&#x1f4dd;前言&#xff1a; 上篇文章C语言——指针&#xff08;二&#xff09;中对&#xff1a;指针的运算和指针变量类型对指针使用的影响开展了进一步的探讨&#xff0c;这篇文章我们继续学习一下指针与一维数组之间的关系&#xff1a; 1&#xff0c;对数组名的理解 2&am…

python变量的作用域

同名变量 内层屏蔽外层 global语句 global强调全局变量

如何使用Windows自带的IIS服务搭建本地站点并远程访问

文章目录 1.前言2.Windows网页设置2.1 Windows IIS功能设置2.2 IIS网页访问测试 3. Cpolar内网穿透3.1 下载安装Cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5.结语 1.前言 在网上各种教程和介绍中&#xff0c;搭建网页都会借助各种软件的帮助&#xf…

(免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐

摘 要 随着时代的不断更新&#xff0c;社会的不断变换&#xff0c;信息技术的飞速发展&#xff0c;计算机科技技术也逐步走向成熟。图书馆管理系统对于当今社会来说是必不可少的一个信息组成部分&#xff0c;它可以管理大量图书、大量读者、让读者有条不紊的进行借阅图书&#…