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:
1
2
Input: ransomNote = "a" , magazine = "b"
Output: false
Example 2:
1
2
Input: ransomNote = "aa" , magazine = "ab"
Output: false
Example 3:
1
2
Input: ransomNote = "aa" , magazine = "aab"
Output: true
Constraints#
1 <= ransomNote.length, magazine.length <= 105
ransomNote
and magazine
consist of lowercase English letters.
Solution#
Method 1 - Using Map#
Code#
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
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
If We Don't Want to Do `Table[c-'A']`:
Java
1
2
3
4
5
6
7
8
9
10
11
12
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 ;
}
1
2
3
4
5
6
7
8
9
10
11
12
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 ;
}