题目
- 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。
- J 中的字母不重复,J 和 S中的所有字符都是字母。字母区分大小写,因此"a"和"A"是不同类型的石头。
示例
①示例1
- 输入: J = “aA”, S = “aAAbbbb”
- 输出: 3
②示例2
- 输入: J = “z”, S = “ZZ”
- 输出: 0
说明
S 和 J 最多含有50个字母。
J 中的字符不重复。
①数据范围
- 65 <= S[i] < 65+26 || 97 <= S[i] < 97+26
- 65 <= J[i] < 65+26 || 97 <= J[i] < 97+26
②相关话题
- 哈希表
- 数组
③题目地址
解题方法
①暴力解法
- 时间复杂度:O(N^2)。
- 空间复杂度:O(1)。
②哈希表
- 数据的范围是一定的,可用数组模拟的哈希表求解,速度最快(用空间换时间)。
- 因为问题中的宝石是唯一的,所以我们需要用哈希表记录所有的宝石字母,然后遍历一遍石头字母,从中找到是宝石的字母。
- 用数组模拟的哈希表求解虽然直观,但是会浪费一些内存空间,所以更好的方法是使用 uthash。
- uthash 是一个用 C 语言编写的开源库,使用宏实现了哈希表的增删改查等功能。
- 时间复杂度:O(N)。
- 空间复杂度:O(N)。
代码详解
- 暴力解法
int numJewelsInStones(char* J, char* S) {
int count = 0, len_S = strlen(S), len_J = strlen(J);
for (int i = 0; i < len_S; i++) {
for (int j = 0; j < len_J; j++) {
if(J[j] == S[i]) {
++count;
break;
}
}
}
return count;
}
- 哈希表
int numJewelsInStones(char* J, char* S) {
int hash[52] = {0}, len_J = strlen(J), len_S = strlen(S), count = 0;
// 字母包括小写字母和大写字母。
// 将J中字母存入哈希表中。
for (int i = 0; i < len_J; i++) {
if (islower(J[i]))
hash[J[i]-'a'] = 1;
else
hash[J[i]-'A'+26] = 1;
}
// 判断石头字母是不是宝石。
for (int i = 0; i < len_S; i++) {
if ((islower(S[i]) && hash[S[i]-'a']) || (!islower(S[i]) && hash[S[i]-'A'+26]))
count++;
}
return count;
}
- uthash
int numJewelsInStones(char* J, char* S) {
struct hash {
int value;
// makes this structure hashable.
UT_hash_handle hh;
};
struct hash *hashTable = NULL;
int len_J = strlen(J), len_S = strlen(S), count = 0;
for (int i = 0; i < len_J; i++) {
struct hash *h = malloc(sizeof(struct hash));
h->value = J[i];
// 将J中字母存入哈希表中。
HASH_ADD_INT(hashTable, value, h);
}
for (int i = 0; i < len_S; i++) {
struct hash *h;
int n = S[i];
HASH_FIND_INT(hashTable, &n, h);
// 判断石头字母是不是宝石。
if (h)
count++;
}
return count;
}
附录
- 我的个人博客:messi1002.top
- 如有错误或疑惑之处 请联系 wjymessi@163.com
- 所有题目解答:fork me on github