优质博文:IT-BLOG-CN
一、题目
给你两个字符串:ransomNote
和magazine
,判断ransomNote
能不能由magazine
里面的字符构成。如果可以,返回true
;否则返回false
。magazine
中的每个字符只能在ransomNote
中使用一次。
示例 1:
输入:ransomNote = "a", magazine = "b"
输出:false
示例 2:
输入:ransomNote = "aa", magazine = "ab"
输出:false
示例 3:
输入:ransomNote = "aa", magazine = "aab"
输出:true
1 <= ransomNote.length, magazine.length <= 105
ransomNote
和magazine
由小写英文字母组成
二、代码
【1】Map: 创建一个Map
,key
存放magazine
字符,value
存放count
, 遍历ransomNote
对count
进行减小,如果小于0
,说明不包含直接退出。
java
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
// 创建一个Map, key 存放 magazine 字符,value存放count, 遍历 ransomNote 对 count进行减小,如果小于0,说明不包含
Map<Character, Integer> map = new HashMap();
for (int i = 0; i < magazine.length(); i++) {
map.put(magazine.charAt(i), map.getOrDefault(magazine.charAt(i), 0) + 1);
}
for (int i = 0; i < ransomNote.length(); i++) {
int count = map.getOrDefault(ransomNote.charAt(i), 0);
map.put(ransomNote.charAt(i), --count);
if (count < 0) {
return false;
}
}
return true;
}
}
时间复杂度: O(m+n)
其中m
表示ransomNote
的长度,n
表示magazine
的长度。
空间复杂度: O(m)
其中m
表示ransomNote
的长度。
【2】字符统计: 如果字符串magazine
的长度小于字符串ransomNote
的长度,则我们可以肯定magazine
无法构成ransomNote
,此时直接返回false
。首先统计magazine
中每个英文字母a
的次数cnt[a]
,再遍历统计ransomNote
中每个英文字母的次数,如果发现ransomNote
中存在某个英文字母c
的统计次数大于magazine
中该字母统计次数cnt[c]
,则此时我们直接返回false
。
java
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
// 创建一个26个字母长度的数组,下标表示字母,value表示个数
int[] letter = new int[26];
for (char c : magazine.toCharArray()) {
letter[c - 'a']++;
}
for (char c : ransomNote.toCharArray()) {
letter[c - 'a']--;
if (letter[c - 'a'] < 0) {
return false;
}
}
return true;
}
}
时间复杂度: O(m+n)
其中m
是字符串ransomNote
的长度,n
是字符串magazine
的长度,我们只需要遍历两个字符一次即可。
空间复杂度: O(∣S∣)
,S
是字符集,这道题中S
为全部小写英语字母,因此∣S∣=26
。