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

请添加图片描述


☘前言☘

今天是算法零基础打卡的第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;
}

📑写在最后

最近忙于更新自己的一些总结文章,这个系列更新的较晚,大家如果喜欢还希望给个点赞收藏啥的 我会继续更新下去的0.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XingleiGao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值