宝石与石头【LC771】
给你一个字符串
jewels
代表石头中宝石的类型,另有一个字符串stones
代表你拥有的石头。stones
中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。字母区分大小写,因此
"a"
和"A"
是不同类型的石头。
哈希表
-
思路
使用哈希表存储石头中宝石的类型,遍历
stones
,如果某个字符在哈希表中,那么数量+1 -
实现
class Solution { public int numJewelsInStones(String jewels, String stones) { Set<Character> set = new HashSet<>(); for (char c : jewels.toCharArray()){ set.add(c); } int res = 0; for (char c : stones.toCharArray()){ if (set.contains(c)){ res++; } } return res; } }
- 复杂度
- 时间复杂度: O ( n ) \mathcal{O}(n) O(n)
- 空间复杂度: O ( n ) \mathcal{O}(n) O(n)
- 复杂度
状态压缩
-
思路
- 字符串只有字母组成,那么一共有26*2个字母,而不同字母的低6位不同,因此可以使用一个64位整数来代替哈希表,当某一位为1时表示对应字母为宝石
- 大写字母二进制的低 666 位是从 000001开始的(对应大写字母 A),一直到 011010(对应大写字母 Z)。
小写字母二进制的低 666 位是从 100001 开始的(对应小写字母 a),一直到 111010(对应小写字母 z),即十进制的 58。
- 大写字母二进制的低 666 位是从 000001开始的(对应大写字母 A),一直到 011010(对应大写字母 Z)。
- m a s k ∣ = 1 L < < ( c & 63 ) mask |= 1L << (c \& 63) mask∣=1L<<(c&63):将第c & 63位赋值为1
- a n s + = ( m a s k > > ( c & 63 ) ) & 1 ans+=(mask >> (c \& 63)) \& 1 ans+=(mask>>(c&63))&1:如果mask的第c & 63位为1,那么结果+1
- 字符串只有字母组成,那么一共有26*2个字母,而不同字母的低6位不同,因此可以使用一个64位整数来代替哈希表,当某一位为1时表示对应字母为宝石
-
实现
class Solution { public int numJewelsInStones(String jewels, String stones) { // 把 jewels 转换成字符集合 mask long mask = 0; for (char c : jewels.toCharArray()) mask |= 1L << (c & 63); // 统计有多少 stones[i] 在集合 mask 中 int ans = 0; for (char c : stones.toCharArray()) ans += (mask >> (c & 63)) & 1; return ans; } } 作者:灵茶山艾府 链接:https://leetcode.cn/problems/jewels-and-stones/solutions/2356253/ben-ti-zui-you-jie-xian-xing-shi-jian-ch-ddw3/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 复杂度
- 时间复杂度: O ( n ) \mathcal{O}(n) O(n)
- 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)
- 复杂度