stones
string are also present in the jewels
string.jewels
string.stones
string.jewels
string.jewels
string for each stone, resulting in a linear search for every stone.jewels
string, we increment the counter.
The brute force solution is inefficient because for every stone in the stones
string, we are performing a membership check against the jewels
string. This results in a time complexity of O(n * m)
, which can be slow when both strings are long.
jewels
string is converted into a set. Sets provide an average O(1)
time complexity for membership checks, which significantly reduces the number of operations compared to the brute force solution.
The “Jewels and Stones” problem is a classic example of frequency analysis and efficient lookup. You're given two strings:
jewels
: A string representing the types of stones that are jewels.stones
: A string representing the stones you have, where each character is a type of stone.
The task is to count how many stones are also jewels. For example, given jewels = "aA"
and stones = "aAAbbbb"
, the output should be 3
, because there are two 'A'
s and one 'a'
in stones
.
This problem is an excellent introduction to the importance of choosing the right data structure. It demonstrates how sets can optimize search operations, and it forms a foundation for more advanced tasks involving frequency counting, character analysis, and hash-based membership checking.
The brute-force method loops through each character in the stones
string and, for each one, checks if it exists in the jewels
string.
Since jewels
is treated as a normal string, each check takes O(m)
time (where m
is the length of the jewels
string). If there are n
characters in stones
, the total time complexity becomes O(n Ă— m)
.
To improve performance, we can convert the jewels
string into a set. Sets in most programming languages provide average O(1)
lookup time.
This turns the nested loop into a single pass through the stones
string.
Here’s the optimized process:
jewels
to a set called jewelSet
.stone
in stones
.stone
is in jewelSet
, increment the counter.
Input: jewels = "aA"
, stones = "aAAbbbb"
jewelSet = {'a', 'A'}
stones
: 'a' → ✔️, 'A' → ✔️, 'A' → ✔️, 'b' → ✖️, 'b' → ✖️, 'b' → ✖️, 'b' → ✖️3
Time Complexity: O(n + m), where n
is the length of stones
and m
is the length of jewels
. Creating the set takes O(m)
, and scanning the stones takes O(n)
.
Space Complexity: O(m) to store the jewelSet
.
jewels
is empty → result is always 0.stones
is empty → result is always 0.'a'
and 'A'
are treated as different characters.The “Jewels and Stones” problem is a simple but powerful illustration of how using the right data structure can transform a slow brute-force solution into an efficient one. It introduces core concepts like hash set lookup, character iteration, and membership testing—all of which are vital for handling real-world data efficiently.