Learnitweb

LeetCode 771: Jewels and Stones

Problem Statement

You are given two strings:

  • J representing types of jewels. Each character is a type of jewel.
  • S representing stones you have. Each character is a stone you own.

You want to know how many of the stones you have are also jewels.

Example:

Input: J = "aA", S = "aAAbbbb"
Output: 3
Explanation: You have 3 jewels: 'a', 'A', 'A'

Constraints:

  • All characters in J and S are letters.
  • Letters are case-sensitive, so “a” and “A” are different types.

Approach to Solve the Problem (Simple Language)

  1. Identify jewels: We need a quick way to check whether a stone is a jewel.
  2. Iterate stones: For each stone in S, check if it exists in J.
  3. Count matches: Keep a counter that increases each time a stone is a jewel.

Optimized idea:

  • Using a HashSet for jewels allows O(1) lookup time for each stone.
  • Iterate through all stones, check if they exist in the HashSet, and increment a counter if yes.

Steps in short:

  1. Convert string J into a HashSet.
  2. Initialize count = 0.
  3. For each character in S:
    • If the character exists in the HashSet, increment count.
  4. Return count.

This approach ensures fast lookup and is simple to understand.


Java Code Solution

import java.util.HashSet;
import java.util.Set;

public class JewelsAndStones {
    
    public static int numJewelsInStones(String J, String S) {
        // Step 1: Store all jewels in a HashSet
        Set<Character> jewels = new HashSet<>();
        for (char j : J.toCharArray()) {
            jewels.add(j);
        }

        // Step 2: Count stones that are jewels
        int count = 0;
        for (char s : S.toCharArray()) {
            if (jewels.contains(s)) {
                count++;
            }
        }

        return count;
    }

    public static void main(String[] args) {
        String J = "aA";
        String S = "aAAbbbb";
        int result = numJewelsInStones(J, S);
        System.out.println("Number of jewels in stones: " + result); // Output: 3
    }
}

Dry Run Example

Input:

J = "aA"
S = "aAAbbbb"

Step-by-step execution:

  1. Convert J to a HashSet:
HashSet jewels = { 'a', 'A' }
  1. Initialize counter: count = 0
  2. Iterate over each character in S:
StoneIs Jewel?Count
‘a’Yes1
‘A’Yes2
‘A’Yes3
‘b’No3
‘b’No3
‘b’No3
‘b’No3
  1. Return 3 as the total number of jewels.

Textual Diagram for Understanding

J (Jewels) : a A
S (Stones) : a A A b b b b

Step 1: Store jewels in a HashSet -> {a, A}

Step 2: For each stone, check if it's in HashSet:

a -> yes -> count=1
A -> yes -> count=2
A -> yes -> count=3
b -> no  -> count=3
b -> no  -> count=3
b -> no  -> count=3
b -> no  -> count=3

Result: 3

Complexity Analysis

  • Time Complexity: O(J + S)
    • O(J) to create the HashSet.
    • O(S) to iterate through all stones.
  • Space Complexity: O(J) for the HashSet storing jewel types.

This approach is simple, efficient, and works well even if S has thousands of stones.