[解题报告]《算法零基础100讲》(第39讲) 非比较排序 - 计数排序

简介: [解题报告]《算法零基础100讲》(第39讲) 非比较排序 - 计数排序

全文目录

 ☘前言☘

 🎁主要知识点

           计数排序

 📓课后习题

           242. 有效的字母异位词

           215. 数组中的第K个最大元素

           389. 找不同

           645. 错误的集合

           268. 丢失的数字

 📑写在最后

☘前言☘

今天是算法零基础打卡的第39天,今天我先更新题解再写文章。上链接:

《算法零基础100讲》(第39讲) 非比较排序 - 计数排序

全文大约阅读时间: 20min


🧑🏻作者简介:一个从工业设计改行学嵌入式的年轻人

✨联系方式:2201891280(QQ)


🎁主要知识点

计数排序

与hash表类似,将所有元素映射到hash表的下标中。


void CountingSort(int n, int *a) {       // 记数排序
    int i, top; 
    memset(cnt, 0, sizeof(cnt));         // 初始化hash表 
    for(i = 0; i < n; ++i) {             // 插入元素
        ++cnt[ a[i] ];                   
    }
    top = 0;                             // 输出数组顶部元素
    for(i = 0; i < maxk; ++i) {
        while(cnt[i]) {                  // 插入所有这个值
            a[top++] = i;                
            --cnt[i];                    
        }
        if(top == n) {                   // 插入了所有的元素提前跳出
            break;
        }
    }
}



📓课后习题

242. 有效的字母异位词

242. 有效的字母异位词


给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。


解题思路


先利用s做插入,然后利用t做减去,所有hash表都是0就是true,否则false。


bool isAnagram(char * s, char * t){
    int hash[26] = {0};
    for(int i = 0;s[i];++i)//插入s
        hash[s[i] - 'a']++;
    for(int i = 0;t[i];++i)//减去t
        if(hash[t[i] - 'a'])    hash[t[i]-'a']--;
        else    return false;
    for(int i = 0;i < 26;++i)//检查
        if(hash[i]) return false;
    return true;
}


215. 数组中的第K个最大元素

215. 数组中的第K个最大元素


给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。


解题思路


反正就20000个元素,直接用hash表做插入,然后从大到小检测,到第k个元素的时候返回就好了。


char hash[20001];//开堆放爆栈-.-
int findKthLargest(int* nums, int numsSize, int k){
    memset(hash,0,sizeof(hash));//初始化
    for(int i = 0;i < numsSize;i++)//插入
        hash[nums[i] + 10000] ++;
    for(int i = 20000;i > -1;i--)//检测
        if(hash[i]){
            k -= hash[i];
            if(k <= 0) return i-10000;//此次符合要求
        }
    return 0;
}


389. 找不同

389. 找不同


给定两个字符串 s 和 t,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。

请找出在 t 中被添加的字母。


解题思路


位运算yyds,反正就一个不一样,异或一遍剩的就是它。


char findTheDifference(char * s, char * t){
        char ans = 0;
        for(int i = 0;s[i];i++)//异或所有s
            ans ^= s[i];
        for(int j = 0;t[j];++j)//异或所有t
            ans ^= t[j];
        return ans;
}


645. 错误的集合

645. 错误的集合


集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。

给定一个数组 nums 代表了集合 S 发生错误后的结果。

请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。


解题思路


直接hash表就好了,最多也就10000个元素。然后用bool就好。重复元素在遍历的时候顺带拉出来。然后丢失数字扫描所有hash表。


int* findErrorNums(int* nums, int numsSize, int* returnSize){
    bool hash[numsSize+1];
    memset(hash,0,sizeof(hash));
    int *ans = malloc(sizeof(int) * 2);
    *returnSize = 2;
    for(int i = 0;i < numsSize;i++){
        if(hash[nums[i]]) ans[0] = nums[i];//重复数字
        hash[nums[i]] = 1;
    }
    for(int i = 1;i < numsSize + 1;i++)//找丢失
        if(!hash[i])    {ans[1] = i;break;}
    return ans;
}


268. 丢失的数字

268. 丢失的数字


给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。


解题思路


骚一点,把0-n进行一遍异或,然后异或所有的数组剩下的结果就是要的数字0.0


int missingNumber(int* nums, int numsSize){
    unsigned ans = 0;
    for(int i = 0;i < numsSize;++i)//异或所有0-n
        ans ^= nums[i];
    for(int i = 0;i < numsSize + 1;i++)//遍历
        ans ^= i;
    return ans;
}
相关文章
|
5月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
2月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
154 7
|
2月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
128 8
|
3月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
101 9
|
3月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
46 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
3月前
|
搜索推荐 Java Go
深入了解计数排序算法
深入了解计数排序算法
52 4
|
3月前
|
算法 Java 程序员
【算法每日一练及解题思路】有n级台阶,一次只能上1级或2级,共有多少种走法?
本文深入解析了“爬楼梯问题”,探讨了递归与迭代两种解法,并提供了Java代码实现。通过分析问题本质,帮助读者理解动态规划技巧,提高解决实际编程问题的能力。关键词:Java, 算法, 动态规划, 爬楼梯问题, 递归, 迭代。
131 0
|
3月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
37 0
|
3月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
85 0
|
3月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)

热门文章

最新文章