You're given strings jewels
representing the types of stones that are jewels, and stones
representing the stones you have. Each character in stones
is a type of stone you have. You want to know how many of the stones you have are also jewels.
Letters are case sensitive, so "a"
is considered a different type of stone from "A"
.
Example 1:
Input: jewels = "aA", stones = "aAAbbbb" Output: 3
Example 2:
Input: jewels = "z", stones = "ZZ" Output: 0
Constraints:
1 <= jewels.length, stones.length <= 50
jewels
and stones
consist of only English letters.jewels
are unique.The problem asks to count the number of stones that are also jewels. We are given two strings: jewels
containing the types of jewel stones, and stones
containing all the stones we possess.
Approach:
The most efficient approach utilizes a hash table (or set) to store the jewel types for fast lookup. We iterate through the stones
string, checking for each stone whether it exists in the jewel set. If it does, we increment a counter.
Time Complexity Analysis:
jewels
string.stones
string takes O(n) time, where n is the length of the stones
string. Each lookup in the set takes O(1) on average.Therefore, the overall time complexity is O(m + n), which is linear with respect to the input string lengths.
Space Complexity Analysis:
The space complexity is dominated by the set (or hash table) used to store the jewels. In the worst-case scenario, the set will contain m elements. Therefore, the space complexity is O(m), linear with respect to the length of the jewels
string.
Code Explanations (with slight improvements):
The provided solutions are generally efficient, but minor optimizations can be made for readability and potential slight performance gains in certain languages.
Python:
class Solution:
def numJewelsInStones(self, jewels: str, stones: str) -> int:
jewels_set = set(jewels) # More descriptive variable name
count = 0
for stone in stones:
if stone in jewels_set:
count += 1
return count
Java:
class Solution {
public int numJewelsInStones(String jewels, String stones) {
Set<Character> jewelsSet = new HashSet<>();
for (char jewel : jewels.toCharArray()) {
jewelsSet.add(jewel);
}
int count = 0;
for (char stone : stones.toCharArray()) {
if (jewelsSet.contains(stone)) {
count++;
}
}
return count;
}
}
C++:
class Solution {
public:
int numJewelsInStones(string jewels, string stones) {
unordered_set<char> jewelsSet;
for (char jewel : jewels) {
jewelsSet.insert(jewel);
}
int count = 0;
for (char stone : stones) {
if (jewelsSet.count(stone)) { //count() is slightly more efficient than contains() for unordered_set
count++;
}
}
return count;
}
};
Other Languages: The other language solutions follow similar logic, utilizing sets or hash tables for efficient lookup. The key improvements across all languages are using more descriptive variable names and employing the most efficient data structures and operations available for the language. For instance, using HashSet
in Java and unordered_set
in C++ is preferred over arrays for better performance with larger input sizes.