【万人千题】C语言12.2计数总结报告
目录
这里给一个题目 215. 数组中的第K个最大元素 - 力扣(LeetCode) (leetcode-cn.com)
448. 找到所有数组中消失的数字 - 力扣(LeetCode) (leetcode-cn.com)
242. 有效的字母异位词 - 力扣(LeetCode) (leetcode-cn.com)
268. 丢失的数字 - 力扣(LeetCode) (leetcode-cn.com)
389. 找不同 - 力扣(LeetCode) (leetcode-cn.com)
645. 错误的集合 - 力扣(LeetCode) (leetcode-cn.com)
一:知识点
1,概念
今天学习的计数,是最原始的哈希表。
主要的思想在于,把目标数组的每个数映射到另一个计数数组中。
例如,数组arr[0,1,2,3,4,5,6,7,8,9]
我们再开一个数组count[10](注意:这里数组的开的大小主要是根据数据的范围而不是根据目标数组的大小。),那么这个时候我们计数时,++count[ arr[i] ],这时候去遍历arr数组的话,每个对应数组元素的内容就会被映射到count数组中,也就是,count下标对应的就是arr数组中元素的值,而count数组中是在计算这个元素有多少个。这样我们就可以得到每个元素的计数了。
2,应用
这种计数方法有个应用在于:排序。我们可以利用它来进行非比较排序
计数排序是一种非比较的排序,它不需要去比较两个元素的大小才进行排序。我们可以把要排序的数组元素映射到count数组中,然后按顺序输出即可。count数组中大小必然是有序,这样逐个输出之后就可以进行排序。不要忘记,count中大于1的话要输出多次,直到变成0.也就是有多个相同元素的时候。
这里给一个题目 215. 数组中的第K个最大元素 - 力扣(LeetCode) (leetcode-cn.com)
解答如下:
//解法一:
// int cmp(const void*e1,const void*e2)
// {
// if(*(int*)e1<=*(int*)e2)
// return 1;
// else
// return 0;
// }
// int findKthLargest(int* nums, int numsSize, int k)
// {
// qsort(nums,numsSize,sizeof(int),cmp);
// int i=0;
// for(i=0;i<numsSize;i++)
// {
// if(i+1==k)
// return nums[i];
// }
// return 0;
// }
//解法二:
int cnt[20001]={0};
int findKthLargest(int* nums, int numsSize, int k)
{
memset(cnt,0,sizeof(cnt));
int i=0;
for(i=0;i<numsSize;i++)
{
++cnt[nums[i]+10000];
}
int j=0;
for(i=0;i<20001;i++)
{
while(cnt[i]!=0)
{
if(j==numsSize)
break;
nums[j]=i-10000;
j++;
cnt[i]--;
}
}
// printf("%d",nums[]);
for(i=numsSize-1;k;k--,i--)
{
if(k-1==0)
return nums[i];
}
return 0;
}
重要:使用计数排序时 如果发现有不是在int类型中的就需要加一个偏移量,比如目标数组的元素数值范围是-100~100,计数时,我们全加上100,让-100变成count数组中的0下标,再进行计数,而等到排完序还原回去时再让每个下标-100即可。
二:习题
448. 找到所有数组中消失的数字 - 力扣(LeetCode) (leetcode-cn.com)
两种解法:
int hash[100001];
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize)
{
memset(hash,0,sizeof(hash));
int i=0;
for(i=0;i<numsSize;i++)
{
++hash[nums[i]];
}
int *ret=(int*)malloc(sizeof(int)*100000);
int j=0;
for(i=1;i<=numsSize;i++)
{
if(hash[i]==0)
{
ret[j]=i;
j++;
}
}
*returnSize=j;
return ret;
}
解法一的主要思路就是计数,然后遍历cnt的数组,找到在目标范围内没有出现的数即可,
int cmp(const void*e1,const void*e2)
{
return *(int*)e1-*(int*)e2;
}
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize)
{
int i=0;
int *ret=( int*)malloc(sizeof(int)*100000);
qsort(nums,numsSize,sizeof(int),cmp);
int j=1;
int count=0;
for(i=0;i<numsSize;i++)
{
again:
if(i>0&&nums[i]==nums[i-1])
continue;
if(nums[i]==j)
{
j++;
continue;
}
else
{
ret[count]=j;
count++;
j++;
goto again;
}
}
for(;j<=numsSize;j++)
ret[count++]=j;
*returnSize=count;
return ret;
}
解法二就先进行排序,然后i去遍历数组,j来控制需要出现的数。数组中的数有可能出现多次,所进入遍历之后需要判断一下这个是否与前一个相等。判断完后进入下一个判断是否与数组元素相等,相等则证明出现,j++,否则就放入答案数组ret中,然后j++。但是要注意对j最后一个数进行特殊处理。j出来之后,如果不是numsSize就说明自j起到numsSize的数都没有出现过,全部加进去这样就可以啦。
三:小总结
这里还有一些题目,大家可以自己去做做
242. 有效的字母异位词 - 力扣(LeetCode) (leetcode-cn.com)
268. 丢失的数字 - 力扣(LeetCode) (leetcode-cn.com)
389. 找不同 - 力扣(LeetCode) (leetcode-cn.com)
645. 错误的集合 - 力扣(LeetCode) (leetcode-cn.com)
答案在:【万人千题】算法解题报告11.28_C_Ryson的博客-CSDN博客
希望大家可以一起进步呀。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了