【每日一题Day275】LC771宝石与石头 | 哈希表 状态压缩

57 篇文章 0 订阅
18 篇文章 0 订阅

宝石与石头【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。
    • 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
  • 实现

    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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值