目录
零、写在前面
这是打卡的第二十四天,今天题目好多好多啊,主要知识点在
《算法零基础100讲》(第24讲) 字符串算法(四) - 字符计数法https://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. 判定字符是否唯一https://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. 第一个只出现一次的字符https://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. 赎金信https://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. 宝石与石头https://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. 判定是否互为字符重排https://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. 检查是否所有字符出现次数相同
先把所有元素出现的次数保存到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. 有效的字母异位词https://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. 有效的变位词https://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. 判断句子是否为全字母句https://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 个独一无二的字符串https://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 我得再修修,可算开机了,就是蓝屏,呜呜呜。