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

红豆不堪看,满眼相思泪

在这里插入图片描述

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

基数排序
思想:已经给定一个数组,数组中就是我们需要排序的数列,再开辟一个数组,该数组的个数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嘛),就可以使用这种方法,和基数排序原理一样,空间换时间,开空间时一定要的。
 结束啦结束啦,希望你有所收获,这就是我创作的最大动力。

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

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

相关文章

Python入门06布尔值

目录 1 什么是布尔值2 怎么生成布尔值3 在控制程序中使用布尔值4 数据过滤、排序和其他高级操作总结 1 什么是布尔值 首先我们要学习一下布尔值的定义&#xff0c;布尔值是一种数据类型&#xff0c;它只有两个可能的值&#xff1a;True&#xff08;真&#xff09;或 False&…

悠络客受邀出席2023上海区域零售(餐饮)数字化运营实战沙龙研讨会

11月23日&#xff0c;由中国零售&#xff08;餐饮&#xff09;CIO俱乐部、《智慧零售与餐饮》主办的2023上海区域零售&#xff08;餐饮&#xff09;数字化运营实战沙龙研讨会在上海召开&#xff0c;悠络客合伙人兼销售副总裁张勇作为演讲嘉宾受邀出席了本次大会。 本次研讨会汇…

【紫光同创PCIE教程】——使用官方驱动在Windows下进行DMA读写操作/PIO读写操作

本原创教程由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 紫光同创官方主推的是在linux系统下开发驱动和上层软件&#xff0c;相应地&#xff0c;官方提供了在linux一个基于GTK2…

Python链式调用技巧:代码流畅无缝连接

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 链式调用是一种编程风格&#xff0c;它允许将多个方法调用连接在一起&#xff0c;形成一个连贯的操作链。在Python中&#xff0c;链式调用常常用于使代码更简洁、易读&#xff0c;尤其在处理数据处理和函数式编程…

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

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

二叉树题目:祖父结点值为偶数的结点和

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;祖父结点值为偶数的结点和 出处&#xff1a;1315. 祖父结点值为偶数的结点和 难度 5 级 题目描述 要求 给定二…

笔记二十六、React中路由懒加载的扩展使用

26.1 在路由中配置懒加载 lazy routes/index.jsx 代码 import {Navigate} from "react-router-dom"; import Home from "../components/Home"; import About from "../components/About"; // import Classify from "../components/Home/c…

VirtualBox 7.0.8(虚拟机软件)

VirtualBox是一款开源的虚拟机软件&#xff0c;它是使用Qt编写&#xff0c;在Sun被Oracle收购后正式更名成Oracle VM VirtualBox。它可以在VirtualBox上安装并且执行Solaris、Windows、DOS、Linux、OS/2 Warp、BSD等系统作为客户端操作系统。使用者可以在VirtualBox上安装并且运…

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

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

【Openstack Train安装】六、Keystone安装

OpenStack是一个云计算平台的项目&#xff0c;其中Keystone是一个身份认证服务组件&#xff0c;它提供了认证、授权和目录的服务。其他OpenStack服务组件都需要使用Keystone来验证用户的身份和权限&#xff0c;并且彼此之间需要相互协作。当一个OpenStack服务组件接收到用户的请…

五、shell - 算术运算符

目录 1、简介 2、例子 ​​​​​​​1、简介 Shell 和其他编程一样&#xff0c;支持包括&#xff1a;算术、关系、布尔、字符串等运算符。原生 bash 不支持简单的数学运算&#xff0c;但是可以通过其他命令来实现&#xff0c;例如expr。expr 是一款表达式计算工具&#xff…

人工智能的技术研究与安全问题的深入讨论

人工智能&#xff08;AI&#xff09;作为当今世界技术领域的热门话题&#xff0c;吸引了广泛的关注和研究。本文将探讨人工智能技术的最新研究进展&#xff0c;并着重讨论与人工智能安全相关的问题。 引言 人工智能技术的迅速发展为我们的生活带来了翻天覆地的变化。随着科技的…

12月7-8日泰国曼谷,Flat Ads与你相约Affilliate World Asia

12月7-8日,Flat Ads将参加在泰国曼谷举办的Affiliate World Asia Conference,与众多行业人士共话全球流量领域新洞察,探讨行业现状与未来趋势。 据悉,Affiliate World Asia(以下简称AWA)是全球瞩目的移动互联网联盟超级盛会,也是亚洲区域内最大规模的互联网流量大会。这一展会为…

无公网IP环境如何远程访问本地内网搭建的Emby影音库服务器

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

发朋友圈的重要性和黄金时间

一、为什么发朋友圈要选择时间发&#xff1f; 1. 增加曝光率&#xff1a;通过定时自动发朋友圈&#xff0c;可以让更多的人看到你的动态。 2. 提高互动率&#xff1a;定时自动发朋友圈可以保持你的朋友圈活跃度&#xff0c;提高与粉丝的互动率。 3. 增强品牌形象&#xff1a…

LeetCode(44)存在重复元素 II【哈希表】【简单】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 存在重复元素 II 1.题目 给你一个整数数组 nums 和一个整数 k &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c;满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&#xff0c;返回 true &#xf…

Egg.js的方法扩展

Extend-application 方法扩展 eggjs的方法的扩展和编写 Egg.js可以对内部的五种对象进行扩展&#xff0c;以下是可扩展的对象、说明、this指向和使用方式。 application对象方法拓展 按照Egg的约定&#xff0c;扩展的文件夹和文件的名字必须是固定的。比如要对application扩…

羊大师提问,为什么吃得越咸越容易出现健康问题?

羊大师提问&#xff0c;为什么吃得越咸越容易出现健康问题&#xff1f; 在现代社会中&#xff0c;有一种追求咸味食物的趋势&#xff0c;许多人都钟爱于吃咸味食物。吃咸味食物往往容易导致健康问题&#xff0c;引发各种疾病。那么为什么吃的越咸越容易生病呢&#xff1f; 今…

公网穿透和RTC

RTC RTC 是 Real-Time Communication 的简写&#xff0c;正如其中文名称 “即时通讯” 的意思一样&#xff0c;RTC 协议被广泛用于各种即时通讯领域&#xff0c;诸如&#xff1a; 在线教育&#xff1b;直播中的主播连麦 PK&#xff1b;日常生活的音视频电话&#xff1b;.....…

MySQL基本SQL语句(上)

MySQL基本SQL语句&#xff08;上&#xff09; 一、客户端工具的使用 1、客户端工具mysql使用 mysql: mysql命令行工具&#xff0c;一般用来连接访问mysql数据库 选项说明-u, --username指定登录用户名-p, --password指定登录密码(注意是小写p),一定要放到最后面-h, --hostn…