Leetcode 771 宝石与石头
题目描述
给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。
J 中的字母不重复,J 和 S中的所有字符都是字母。字母区分大小写,因此"a"和"A"是不同类型的石头。
解题
拿到题的第一个想法是能不能空间换时间
然后想了想发现不太可能
因为即使把字符串拆分成单个的字符
也需要用循环一个个的遍历
所以这题大概可以直接用循环暴力解
时间复杂度O(MN)
public class Solution {
public int numJewelsInStones(String J, String S) {
int count = 0;
for(int i = 0; i < S.length(); i++)
for(int j = 0; j < J.length(); j++)
if(S.charAt(i) == J.charAt(j)){
count++;
break;
}
return count;
}
}
做完之后就去找题解
发现官方文档中有时间复杂度更小达到O(M+N)的解法
使用了哈希表
其中最有趣的做法就是把int和字母一一对应
出现过的字母赋值为1
未出现的赋值为0
然后判断第二次遍历中字母对应的哈希值是否为0
就可以把两次遍历分开
这种方法可能我在大一的时候见过,但现在见到的着实不多
也算给我一个提醒吧
最后,我看见了一道非常非常优秀的解法
从时间复杂度到空间复杂度都很优秀
在官方题解评论中看到的
@Terminal
朋友的题解
可能是我刚刚开始刷题的原因
看到您的思路真的感到眼前一亮
这位朋友的方法是建立一个长度256的数组,开始数组不进行赋值
此时java会给这些数组中的数全部赋值为0
而后只需要遍历一遍字符串J中字符将“宝石”相关字母全部赋值为1
在遍历字符串S的字符过程中甚至不需进行判断
只需要把S中字符对应的数组中数据相加即可得到“宝石”数目
class Solution2 {
public int numJewelsInStones(String J, String S) {
int len = J.length();
int[] type = new int[256];
for(int i = 0; i < len; i++){
type[J.charAt(i)] = 1;
}
int ans = 0;
len = S.length();
for(int i = 0; i < len; i++){
ans += type[S.charAt(i)];
}
return ans;
}
}
投了原创是因为力扣评论没有单独的链接…
侵删
@Terminal大佬