【万人千题】《算法零基础100讲》(第39讲) 非比较排序 - 计数排序【题解】

目录

传送门

计数排序

课后习题

有效的字母异位词

 数组的第K个最大元素

 丢失的数字

找不同

 错误的集合


传送门

《算法零基础100讲》(第39讲) 非比较排序 - 计数排序_英雄哪里出来-CSDN博客利用哈希思想的排序手段https://blog.csdn.net/WhereIsHeroFrom/article/details/121586835

计数排序

        这个思想挺简单的,就是把一个元素映射到数组下标中去,来完成统计,最后遍历插入到排序数组中去。这种排序速度通常要比比较排序的速度快,时间复杂度O(n+k),k是数的范围。虽然速度快,但是很受数据本身范围的限制。

int hash[MAXN];                            //计数数组
void CountingSort(int *nums,int numsSize) {    
    memset(hash, 0, sizeof(hash));
    int i,top = 0; 
    for(i = 0;i<numsSize;++i) {             
        ++hash[nums[i]];                  //对nums元素进行统计
    }                          
    for(i=0;i<MAXN;++i) {
        while(hash[i]) {                  //当计数不为0
            nums[top++] = i;              //将该数追加至nums
            --hash[i];                    
        }   
        if(top == numsSize) {             //当元素都排完了,就可以退出了                 
            break;
        }
    }
} 

课后习题

有效的字母异位词

有效的字母异位词icon-default.png?t=LA92https://leetcode-cn.com/problems/valid-anagram/

 题目描述:

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

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

思路:对s和t排序,判断是不是相等的

 

int hash[27];
void CountintSort(char *s,int len1){
    memset(hash,0,sizeof(hash));
    int i,top=0;
    for(i=0;i<len1;++i){
        hash[s[i]-'a']++;
    }
    for(i=0;i<26;++i){
        while(hash[i]){
            s[top++] = i+'a';
            hash[i]--;
        }
        if(top == len1)
            break;
    }
}
bool isAnagram(char * s, char * t){
    int i,len1 = strlen(s),len2 = strlen(t),top=0;
    CountintSort(s,len1);       //排序
    CountintSort(t,len2);
    return !strcmp(s,t);        //strcmp 相等返回的是 0
}


 数组的第K个最大元素

数组中的第K个最大元素icon-default.png?t=LA92https://leetcode-cn.com/problems/kth-largest-element-in-an-array/

 题目描述:

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

思路:排序 按要求返回第k大的数

bool cmp(void *a,void *b){
    return *(int*)a < *(int*)b;             //我这里是从大到小排序
}
int findKthLargest(int* nums, int numsSize, int k){
    qsort(nums,numsSize,sizeof(int),cmp);
    return nums[k-1];                       //返回第K大的数
}

 丢失的数字

丢失的数字icon-default.png?t=LA92https://leetcode-cn.com/problems/missing-number/

题目描述: 

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

思路:做差法,将0~n全部相加,再减去nums[0]~nums[n-1],得到的就是缺失的数了

int missingNumber(int* nums, int numsSize){
    int ans=0,i;
    for(i=0;i<numsSize;++i){
        ans += i;               
        ans -= nums[i];
    }
    ans += numsSize;
    return ans;
}

找不同

找不同icon-default.png?t=LA92https://leetcode-cn.com/problems/find-the-difference/

 题目描述:

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

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

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

思路:和上题一样的,做差。

 

char findTheDifference(char * s, char * t){
    int ans=0,i,lent = strlen(t),lens=strlen(s);
    for(i=0;i<lent;++i){
        ans += t[i];
    }
    for(i=0;i<lens;++i){
        ans -= s[i];
    }
    return ans;
}

 错误的集合

错误的集合icon-default.png?t=LA92https://leetcode-cn.com/problems/set-mismatch/

 题目描述:

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

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

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

思路:将元素映射到数组下标来统计,出现两次的就是重复的,零次的就是丢失的

#define MAXN 10001
int hash[MAXN];
int* findErrorNums(int* nums, int numsSize, int* returnSize){
    int i;
    memset(hash,0,sizeof(hash));
    for(i=0;i<numsSize;++i){
        hash[nums[i]]++;
    }
    for(i=1;i<numsSize+1;++i){          //数字范围是 1~n
        if(hash[i] >= 2){
            nums[0] = i;
        }
        else if(hash[i] == 0){
            nums[1] = i;
        }
    }
    *returnSize = 2;
    return nums;
}

 今天的内容挺轻松的,打卡!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

周日加一

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

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

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

打赏作者

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

抵扣说明:

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

余额充值