题解 | 宝石计数 | 多种哈希表的实现方式 | 这里是栈上数组法

宝石计数

https://www.nowcoder.com/practice/d7c20bd9aa094e35b465b566eec86cf2

1. 平衡二叉搜索树 — std::set / std::map

底层数据结构

红黑树(自平衡二叉搜索树),元素按键值有序存储。

时间复杂度

  • 插入、删除、查找:O(log n) 平均 & 最坏
  • 遍历有序:O(n)
  • 前驱后继(lower_bound/upper_bound):O(log n)

空间复杂度

  • O(n),每个节点额外存储左右孩子指针、父节点指针、颜色(通常 3 个指针 + 1 字节),内存开销较大。

使用条件

  • 需要元素按 key 有序(按序遍历、输出排序结果)
  • 需要频繁的范围查询(比 x 大的最小元素、比 x 小的最大元素)
  • 迭代器不能因插入而失效(有稳定迭代器需求)
  • 元素类型没有合适的哈希函数,或担心哈希被卡
  • 数据规模 ≤ 2×10⁵ 且 O(log n) 完全够用

2. 哈希表 — std::unordered_set / std::unordered_map

底层数据结构

开链法(Separate Chaining)哈希表。由一个桶数组(动态扩缩容)和链表/红黑树(当桶内冲突过多时 C++11 后可能转红黑树)构成。

时间复杂度

  • 插入、删除、查找:平均 O(1),最坏 O(n)(大量冲突退化为链表)
  • 不支持顺序查询

空间复杂度

  • O(n),但常数较大(桶数组 + 每个节点的指针/哈希值存储),负载因子默认约 1.0,内存占用通常大于红黑树。

使用条件

  • 只需要快速判存在,不关心顺序
  • 数据分布较均匀,哈希冲突概率低
  • 没有范围查询需求
  • 作为通用哈希表,适用于绝大多数情况,竞赛中极少被故意卡(int/string 等默认哈希很安全)

3. 直接寻址数组 — bool arr[128] / std::array<bool, N>

底层数据结构

把 key 直接当作数组下标,相当于“哈希函数为恒等映射”。每个位置存储一个 bool 或计数。

时间复杂度

  • 插入、删除、查找:严格 O(1),常数极小
  • “哈希函数”就是取下标,零冲突

空间复杂度

  • O(M),M 为 key 域的大小(例如字母大小写共 128,或数字范围 10⁷)。
  • 如果 key 域很大但实际存储元素稀疏,空间浪费严重。

使用条件

  • key 的范围很小且连续/可枚举(如 ASCII 字符、小范围整数)
  • 追求极致速度,同时内存放得下整个域
  • 这是 “用空间换时间”的终极形态,也是竞赛中处理字符集问题的最优解
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param jewels string字符串 
     * @param stones string字符串 
     * @return int整型
     */
    int numJewelsInStones(string jewels, string stones) {
        array<bool,128> isJewel{};
        for(const auto& jewel:jewels) isJewel[jewel]=true;
        int cnt=0;
        for(const auto& stone:stones) cnt+=isJewel[stone];
        return cnt;
    }
};

全部评论

相关推荐

个人背景:学院二本计科专业&nbsp;大二开始实习个人经历:安克创新&nbsp;、理想汽车、字节跳动碎碎念:我做事只有三分钟热度。看到进了大厂的同学,我会羡慕,也会跟着努力上进;但遇到好看的小说,我又会放下手头的事沉迷其中,之前的坚持也就中断了。我有些自卑,总觉得自己学历和外貌都不够好。之前偶然在网上受到关注,我就喜欢上了上网,因为这里有很多人认可我。但我也很在意别人的评价,偶尔看到嘲讽的言论,会触发我的自卑情绪,让我感到愤怒。有时候我会强硬地回怼,有时候又会懦弱地选择无视。我也有虚荣心。不管是拿到安克、理想还是字节的机会,我在分享的时候都会带着这份心思。我会特意强调自己学历不好,是为了衬托出过程的艰难,以此显得自己更厉害。我知道,人往往会炫耀自己缺少的东西,来掩盖内心的空洞。我总想着走捷径,不太喜欢踏踏实实地做事。找实习的时候,我花了更多时间在研究面试技巧上,而不是提升专业能力。我会反复听面试录音分析技巧,看面试教程学习怎么和不同的面试官沟通,还会每天自言自语练习语言表达,同学都觉得我有点奇怪。我的实习生涯里,侥幸和运气占了很大一部分。我总在想,如果有一天我失去了这份幸运,这些特质可能会让我一蹶不振。ps:&nbsp;很多人会问我学习路线和经验&nbsp;但是就像我上面说的&nbsp;我的实习过程靠的很多是关键节点的运气&nbsp;技术上面我可能不如很多人&nbsp;&nbsp;所以请大家理性求助和理性参考我的回答&nbsp;附上我的投递记录
我的offer在哪里...:从去年看到现在,飞升哥就是榜样
我的求职进度条
点赞 评论 收藏
分享
04-01 16:02
已编辑
武汉工程大学 Java
牛客98843461...:处女面??我还种马面渣男面处男面呢
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务