[解题报告](第24讲) 字符串算法(四) - 字符计数法

目录

零、写在前面

一、主要知识点

        1.字符记数

二、课后习题 

面试题 01.01. 判定字符是否唯一

剑指 Offer 50. 第一个只出现一次的字符

383. 赎金信

771. 宝石与石头

 面试题 01.02. 判定是否互为字符重排

1941. 检查是否所有字符出现次数相同

242. 有效的字母异位词

 剑指 Offer II 032. 有效的变位词

 1832. 判断句子是否为全字母句

2053. 数组中第 K 个独一无二的字符串

 写在最后


零、写在前面

         这是打卡的第二十四天,今天题目好多好多啊,主要知识点在

《算法零基础100讲》(第24讲) 字符串算法(四) - 字符计数法icon-default.png?t=LA92https://blog.csdn.net/WhereIsHeroFrom/article/details/121295716


一、主要知识点

        1.字符记数

        可以利用hash表来记录字符串的数量,如果字符串只包含小写字母,还可以进一步压缩。

    int hash[26] ={0};    //hash表顺带初始化
    for(int i = 0;s[i];++i)
        hash[s[i] - 'a']++;    //统计数量

二、课后习题 

面试题 01.01. 判定字符是否唯一

面试题 01.01. 判定字符是否唯一icon-default.png?t=LA92https://leetcode-cn.com/problems/is-unique-lcci/思路

利用hash表,扫到扫过的字母就直接返回假,如果全扫完也没遇到就返回真。

bool isUnique(char* astr){
    bool hash[256];
    memset(hash,0,sizeof(hash));
    for(int i = 0;astr[i];++i)
        if(!hash[astr[i]])  hash[astr[i]]++;
        else return false;
    return true;
}

结果分析

凑合玩玩


剑指 Offer 50. 第一个只出现一次的字符

剑指 Offer 50. 第一个只出现一次的字符icon-default.png?t=LA92https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/思路

先用hash表统计所有字母的出现次数,再扫描hash表,如果有等于1就的返回

没有就返回空格。

这道题返回的是一个字符!所以可以直接返回一个值!

char firstUniqChar(char* s){
    int hash[26] ={0};    //hash表+初始化
    for(int i = 0;s[i];++i)    //记录hash值
        hash[s[i] - 'a']++;
    for(int i = 0;s[i];++i)    //遍历hash表
        if(hash[s[i] - 'a'] == 1)   return s[i];
    return ' ';    //没找到返回空格
}

结果分析

说的过去


383. 赎金信

383. 赎金信icon-default.png?t=LA92https://leetcode-cn.com/problems/ransom-note/思路

这次其实只是更新hash表的方式不同

首先,扫描magazine将所有出现的元素和个数都插入hash表内

然后,扫描ransom,扫到一个字符将对应的hash表值减1.

bool canConstruct(char * ransomNote, char * magazine){
    int hash[256] = {0};    //hash表
    for(int i = 0;magazine[i];++i)//扫描magazine更新hash表
        hash[magazine[i]] ++;
    for(int i = 0;ransomNote[i];++i)    //扫描ransom更新hash表
        if(!hash[ransomNote[i]])  return false;//对应元素不够用?
        else hash[ransomNote[i]]--;
    return true;
}

结果分析

 还是可以的


771. 宝石与石头

771. 宝石与石头icon-default.png?t=LA92https://leetcode-cn.com/problems/jewels-and-stones/思路

先扫描J中所有元素,然后根据hash表判断s中元素进行统计。

int numJewelsInStones(char * jewels, char * stones){
    bool has[256] = {0};    //hash表
    int ans = 0;
    for(int i = 0; jewels[i]; ++i)    //更新hash表
        if(has[jewels[i]] == 0) has[jewels[i]] = 1;
    for(int i = 0; stones[i]; ++i)//根据hash统计
        if(has[stones[i]] == 1) ans++;
    return ans;
}

结果分析

还可以的


 面试题 01.02. 判定是否互为字符重排

面试题 01.02. 判定是否互为字符重排icon-default.png?t=LA92https://leetcode-cn.com/problems/check-permutation-lcci/思路

如果对应元素的个数相同,并且两个字符串长度相同贼满足条件。

bool CheckPermutation(char* s1, char* s2){
    int hash[256] = {0},count = 0;//hash表
    for(int i = 0;s1[i];++i){    //查看s1的所有元素
        hash[s1[i]]++;
        count++;
    }
    for(int i = 0;s2[i];++i){    //对比s2与s1中的元素是否相同
        if(hash[s2[i]])  hash[s2[i]]--;//找到了返回
        else return false;
        if(!(count--)) return false;
    }
    if(count == 0)return true;//长度相等
    else return false;    //s1比s2长
}

结果分析

很凑合了


1941. 检查是否所有字符出现次数相同

1941. 检查是否所有字符出现次数相同icon-default.png?t=LA92https://leetcode-cn.com/problems/check-if-all-characters-have-equal-number-of-occurrences/思路

先把所有元素出现的次数保存到hash表内,然后看hash表内非0元素是否与最大值相等。

bool areOccurrencesEqual(char * s){
    int max = 0,hash[26] = {0};//hash表和最大值的初始化
    for(int i = 0;s[i];++i){    //统计信息
        hash[s[i]-'a']++;
        if(hash[s[i]-'a'] > max) max = hash[s[i]-'a'];
    }
    for(int i = 0;i < 26;i++)    //看是否满足要求
        if(hash[i] && hash[i] != max)  return false;
    return true;
}

结果分析

凑合


242. 有效的字母异位词

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

分两步走。

先判断是否所有元素都有

再判断是否长度一样

bool isAnagram(char * s, char * t){
    int hash[26] = {0};
    for(int i = 0;s[i];++i)    //插入hash统计
        hash[s[i] - 'a']++;
    for(int i = 0;t[i];++i)    //看所有元素是否都够用
        if(hash[t[i] - 'a'])    hash[t[i]-'a']--;
        else    return false;
    for(int i = 0;i < 26;++i)
        if(hash[i]) return false;//hash表还有值说明长度不同
    return true;
}

结果分析

凑合玩玩


 剑指 Offer II 032. 有效的变位词

剑指 Offer II 032. 有效的变位词icon-default.png?t=LA92https://leetcode-cn.com/problems/dKk3P7/思路

分两步走

统计每个字符出现的次数是否相同

判断是否长度相等或者是否完全相同

bool isAnagram(char * s, char * t){
    int hash[26] = {0};
    int ssize= 0,tsize = 0;
    for(ssize = 0;s[ssize];++ssize)//统计单词
        hash[s[ssize] - 'a']++;
    for(tsize = 0;t[tsize];++tsize)//查看单词是否出现次数相同
        if(hash[t[tsize] - 'a'])    hash[t[tsize]-'a']--;
        else    return false;
    if(ssize != tsize || !strcmp(s,t))   return false;    //长度是否相同 并且不完全相同
    return true;
}

解题思路

凑凑合和


 1832. 判断句子是否为全字母句

1832. 判断句子是否为全字母句icon-default.png?t=LA92https://leetcode-cn.com/problems/check-if-the-sentence-is-pangram/思路

先用hash表统计所有出现的字母,

再全扫描hash表看是否有未出现的字母就好了呗?

bool checkIfPangram(char * sentence){
    char hash[26] = {0};
    for(int i = 0;sentence[i];++i)//查看出现的元素
        hash[sentence[i] - 'a'] = true;
    for(int i = 0;i < 26;i++)    //查看是否有未出现元素
        if(!hash[i])    return false;
    return true;
}

解题思路

海星


2053. 数组中第 K 个独一无二的字符串

2053. 数组中第 K 个独一无二的字符串icon-default.png?t=LA92https://leetcode-cn.com/problems/kth-distinct-string-in-an-array/思路

利用一个字符指针数组保存不一样的字符串

当扫描同样的字符的时候将对应的hashnum值+1

扫描整个hash表查找只出现一次的hashnum值,找到一个k-1,最终找到就返回对应hash值。找不到就返回一个申请的空字符串

char * kthDistinct(char ** arr, int arrSize, int k){
    int count = 0,ansnum = 0;
    char * hash[1000];    //收集不同的字符串
    int hashnum[1000]= {0};    //收集对应字符串出现次数
    for(int i = 0;i < arrSize;i++){    //扫描所有的arr进行hash和hashnum的插入
        int j = 0;
        for(j = 0;j < count;j++)
            if(strcmp(hash[j],arr[i]) == 0){//出现过
                hashnum[j] ++;
                break;
            }
        if(j == count) {        //未出现过
            hash[count++] = arr[i];
            hashnum[count - 1] ++;
        }
    }
    for(int i = 0,j = k;j > 0 && i < count;i++){    //寻找对应的字符串地址
        if(hashnum[i] == 1)j--;
        if(j == 0)  return hash[i];
    }
    char *s = malloc(sizeof(char));//空字符串 必须要申请
    s[0] = 0;
    return s;
}

结果分析

写完了,终于!


 写在最后

不想待在寝室,大家一定要离床远一点。冬天了,大家注意保暖,别感冒了!

平板的win11还差个acpi 我得再修修,可算开机了,就是蓝屏,呜呜呜。

猜你喜欢

转载自blog.csdn.net/qq_17593855/article/details/121302456