哈希算法题目:宝石与石头
字数 1475 2025-10-25 18:57:06
哈希算法题目:宝石与石头
题目描述
给定一个字符串 jewels 代表宝石的类型,以及一个字符串 stones 代表你拥有的石头。stones 中的每个字符代表了一种你拥有的石头的类型。你想知道你拥有的石头中有多少是宝石。
字母区分大小写,因此 "a" 和 "A" 是不同类型的石头。
示例 1:
输入: jewels = "aA", stones = "aAAbbbb"
输出: 3
解释: 字符串 stones 中有三个 'a' 或 'A' 的字符,它们都是宝石。
示例 2:
输入: jewels = "z", stones = "ZZ"
输出: 0
解释: 大小写敏感,stones 中的 'Z' 和 'z' 不同,所以没有宝石。
解题过程
-
问题分析
- 目标:统计字符串
stones中有多少个字符出现在字符串jewels中。 - 核心操作:对于
stones中的每一个字符,我们需要快速判断它是否存在于jewels中。 - 关键点:字母区分大小写。
- 目标:统计字符串
-
选择数据结构
- 最直接的思路是使用两层循环:遍历
stones中的每个字符,对于每个字符,再遍历一遍jewels看是否存在。这种方法的时间复杂度是 O(n*m),其中 n 是stones的长度,m 是jewels的长度。当字符串较长时,效率较低。 - 优化思路:为了快速判断一个元素是否存在,哈希表(在 Python 中常用集合
set)是最佳选择。我们可以先将所有宝石类型存入一个集合,这个集合的查找操作时间复杂度为 O(1)。
- 最直接的思路是使用两层循环:遍历
-
算法步骤
-
步骤一:构建宝石集合
创建一个哈希集合jewel_set,遍历字符串jewels,将其中的每一个字符添加到集合中。- 为什么用集合?集合保证了元素的唯一性,并且提供了常数时间复杂度的成员检查(
in操作)。 - 例如,对于
jewels = "aA",jewel_set的内容是{'a', 'A'}。
- 为什么用集合?集合保证了元素的唯一性,并且提供了常数时间复杂度的成员检查(
-
步骤二:遍历并统计石头
初始化一个计数器count,初始值为 0。
遍历字符串stones中的每一个字符:- 对于当前字符
stone,检查它是否存在于我们刚刚创建的集合jewel_set中。 - 如果存在(
if stone in jewel_set),说明这是一颗宝石,将计数器count加 1。 - 如果不存在,则不做任何操作,继续检查下一个字符。
- 对于当前字符
-
步骤三:返回结果
遍历完stones中的所有字符后,计数器count的值就是宝石的数量,将其作为结果返回。
-
-
复杂度分析
- 时间复杂度:O(m + n)
- 构建宝石集合需要遍历
jewels字符串,时间复杂度为 O(m),m 是jewels的长度。 - 遍历并统计
stones需要 O(n) 的时间,n 是stones的长度。 - 总时间复杂度为 O(m + n),这比最初的 O(m*n) 要高效得多。
- 构建宝石集合需要遍历
- 空间复杂度:O(m)
- 主要是用于存储宝石集合
jewel_set所消耗的空间,在最坏情况下(所有宝石字符都不同),需要 O(m) 的额外空间。
- 主要是用于存储宝石集合
- 时间复杂度:O(m + n)
总结
这道题展示了哈希集合在快速查找方面的经典应用。通过将需要判断的“目标集合”(宝石)预先存入哈希表,我们将原本需要线性扫描的查找操作优化成了常数时间,从而显著提升了整个算法的效率。解决此类“判断存在性”的问题,应优先考虑使用哈希表(或集合)来优化性能。