leetcode 383赎金信 C语言
题目要求判断一个字符串(赎金信)中的字符是否可以由另一个字符串(杂志)中的字符组成,即赎金信中的每个字符都必须在杂志中至少出现相同次数。
解题思路:
计数法:
- 首先统计杂志中每个字符的出现次数,可以使用数组来记录每个字符的频率。
- 然后遍历赎金信中的每个字符,对应减少杂志中该字符的计数,如果杂志中对应字符的计数小于赎金信中的需要,则说明无法满足条件。
具体步骤:
- 使用一个大小为26的数组
count
来统计杂志中每个字符的频率,其中下标表示字符(例如'a'
对应索引0,'b'
对应索引1,以此类推)。 - 第一次遍历杂志字符串,增加对应字符的计数。
- 第二次遍历赎金信字符串,减少对应字符的计数,并判断计数是否小于零(即赎金信需要的字符在杂志中没有足够的数量)。
- 使用一个大小为26的数组
代码实现:
c#include <stdio.h>
#include <stdbool.h>
bool canConstruct(char * ransomNote, char * magazine){
int count[26] = {0}; // 数组用于统计杂志中每个字符的出现次数
// 统计杂志中每个字符的频率
for (int i = 0; magazine[i] != '\0'; ++i) {
count[magazine[i] - 'a']++;
}
// 检查赎金信中的字符是否可以由杂志中的字符组成
for (int i = 0; ransomNote[i] != '\0'; ++i) {
count[ransomNote[i] - 'a']--;
if (count[ransomNote[i] - 'a'] < 0) {
return false;
}
}
return true;
}
int main() {
char ransomNote[] = "aa";
char magazine[] = "aab";
if (canConstruct(ransomNote, magazine)) {
printf("Yes, you can construct the ransom note.\n");
} else {
printf("No, you cannot construct the ransom note.\n");
}
return 0;
}
解析:
count
数组用于记录每个字符出现的次数,初始化为0。- 第一个循环遍历杂志字符串
magazine
,增加对应字符的计数。 - 第二个循环遍历赎金信字符串
ransomNote
,减少对应字符的计数,如果计数小于零则返回 false。 - 如果所有字符都能满足条件,则返回 true。
这种解法的时间复杂度为 O(m + n),其中 m 是杂志字符串的长度,n 是赎金信字符串的长度。空间复杂度为 O(1),因为数组 count
的大小是固定的(26个字母)。
这样的算法能够有效地判断赎金信是否可以由杂志中的字符构成,并且性能较为优秀。