Ransom Note easy
Problem Statement
Given two strings ransomNote
and magazine
, return true
if ransomNote
can be constructed from magazine
and false
otherwise.
Each letter in magazine
can only be used once in ransomNote
.
Example 1:
Input: ransomNote = "a", magazine = "b" Output: false
Example 2:
Input: ransomNote = "aa", magazine = "aab" Output: true
Steps
-
Create a frequency counter for the
magazine
string: This will store the count of each character inmagazine
. We can use a dictionary for this. -
Iterate through the
ransomNote
string: For each character inransomNote
, check if it exists in the frequency counter. -
Check frequency: If the character exists, decrement its count in the frequency counter. If the count becomes 0, remove the character from the counter.
-
Handle missing characters: If a character from
ransomNote
is not found in the frequency counter (or its count is already 0), returnFalse
immediately, as we cannot construct theransomNote
. -
Return True if successful: If the loop completes without finding any missing characters, it means we can construct
ransomNote
frommagazine
, so returnTrue
.
Explanation
The solution leverages the idea of frequency counting. By tracking the frequency of characters in the magazine
, we can efficiently check if we have enough of each character to build the ransomNote
. Using a dictionary for the frequency counter allows for O(1) lookup time for character counts. This makes the overall algorithm quite efficient.
Code
from collections import Counter
def canConstruct(ransomNote, magazine):
"""
Checks if ransomNote can be constructed from magazine.
Args:
ransomNote: The string to be constructed.
magazine: The string containing available characters.
Returns:
True if ransomNote can be constructed, False otherwise.
"""
mag_count = Counter(magazine) # Create frequency counter for magazine
for char in ransomNote:
if char not in mag_count or mag_count[char] == 0:
return False # Character not found or count is 0
mag_count[char] -= 1 # Decrement count
return True # All characters found
# Example usage
ransomNote1 = "a"
magazine1 = "b"
print(f"Can construct '{ransomNote1}' from '{magazine1}': {canConstruct(ransomNote1, magazine1)}") # Output: False
ransomNote2 = "aa"
magazine2 = "aab"
print(f"Can construct '{ransomNote2}' from '{magazine2}': {canConstruct(ransomNote2, magazine2)}") # Output: True
ransomNote3 = "aa"
magazine3 = "aba"
print(f"Can construct '{ransomNote3}' from '{magazine3}': {canConstruct(ransomNote3, magazine3)}") #Output: False
Complexity
-
Time Complexity: O(m + n), where 'm' is the length of
ransomNote
and 'n' is the length ofmagazine
. Creating the counter is O(n), and iterating throughransomNote
is O(m). Dictionary lookups are O(1) on average. -
Space Complexity: O(min(m, n)), The space used by the
mag_count
dictionary is at most the size of the smaller string's unique characters (because it's a frequency counter). In the worst-case scenario, all characters are unique, resulting in this space complexity.