小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
原题链接
771. 宝石与石头 - 力扣(LeetCode) (leetcode-cn.com)
题目描述
给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。
J 中的字母不重复,J 和 S中的所有字符都是字母。字母区分大小写,因此"a"和"A"是不同类型的石头。
测试用例
示例 1:
输入: J = "aA", S = "aAAbbbb"
输出: 3
示例 2:
输入: J = "z", S = "ZZ"
输出: 0
参数限制
- S 和 J 最多含有50个字母。
- J 中的字符不重复。
分析
用通俗的话来说,有两个字符串 a, b,其中,a 中的单个字符都不会重复,需要判断出来,b 中的单个字符如果出现在 a 中,则需要计数 +1,最后返回这个值
代码
一个简单的解法,将 a 中的数据转化为 Set,然后遍历 b 的字符,判断并计数
var numJewelsInStones = function(jewels, stones) {
let set = new Set(jewels.split(''));
let count = 0;
stones.split('').forEach(n=>{
if(set.has(n)) count++;
})
return count;
};
从答案来,耗时米勉强,但内存占用不尽人意
解法 2
上面的方法是使用 Set 来优化检索效率,总的执行时间需要分别遍历 2 个字符串,再加上 hashset 的检索耗时
这次,我们优化掉 hashset 的检索,直接使用一个 object 来存储字符串 b 中各个字符出现的次数
然后再遍历一次 a,遍历的时候,对每个字符 n 做 sum += obj[n] || 0,简单粗暴
var numJewelsInStones = function(jewels, stones) {
let obj = {};
stones.split('').forEach(n=>{
obj[n]=(obj[n]||0)+1;
})
let count = 0;
jewels.split('').forEach(n=>count += (obj[n]||0));
return count;
};
但这效果就有点不太满意了,讲道理,hash 的检索耗时去掉了,使用 obj 来替代 set,内存也没降到多少
官方题解
使用的 Set,但写起来让人更加惊艳
var numJewelsInStones = function(jewels, stones) {
const jewelsSet = new Set(jewels.split(''));
return stones.split('').reduce((prev, val) => {
return prev + jewelsSet.has(val);
}, 0);
};
多次测试后,发现确实提升了一点点
今天的力扣刷题就分享到这里,感谢大家的阅读~