Ransom Note
EasyUpdated: Aug 2, 2025
Practice on:
Problem
Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.
Each letter in magazine can only be used once in ransomNote.
Examples
Example 1:
Input: ransomNote = "a", magazine = "b"
Output: false
Example 2:
Input: ransomNote = "aa", magazine = "ab"
Output: false
Example 3:
Input: ransomNote = "aa", magazine = "aab"
Output: true
Constraints
1 <= ransomNote.length, magazine.length <= 105ransomNoteandmagazineconsist of lowercase English letters.
Solution
Method 1 - Using Map
Code
Java
public boolean canConstruct3(String ransomNote, String magazine) {
Map<Character, Integer> map = new HashMap<>();
for (char c : magazine.toCharArray()) {
int count = map.containsKey(c) ? map.get(c) + 1 : 1;
map.put(c, count);
}
for (char c : ransomNote.toCharArray()) {
int newCount = map.containsKey(c) ? map.get(c) - 1 : -1;
if (newCount == -1) return false;
map.put(c, newCount);
}
return true;
}
Method 2 - Using Array as Map
The efficiency of the code is primarily due to using the ASCII value of each character in the string as an array index, allowing direct access and thereby significantly improving the algorithm's speed.
Code
Java
public boolean canConstruct2(String ransomNote, String magazine) {
int[] table = new int[26];
for (char c: magazine.toCharArray()) {
table[c - 'a']++;
}
for (char c: ransomNote.toCharArray()) {
if (--table[c - 'a']<0) {
return false;
}
}
return true;
}
If we don't want to do table[c-'a']:
public boolean canConstruct(String ransomNote, String magazine) {
int[] table = new int[128];
for (char c: magazine.toCharArray()) {
table[c]++;
}
for (char c: ransomNote.toCharArray()) {
if (--table[c]<0) {
return false;
}
}
return true;
}