❓383. 赎金信
难度:简单
给你两个字符串: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 < = r a n s o m N o t e . l e n g t h , m a g a z i n e . l e n g t h < = 1 0 5 1 <= ransomNote.length, magazine.length <= 10^5 1<=ransomNote.length,magazine.length<=105
ransomNote
和magazine
由小写英文字母组成
💡思路:哈希解法
因为题目所只有小写字母,那可以采用空间换取时间的哈希策略:
- 用一个长度为
26
的数组还记录magazine
里字母出现的次数; - 然后再用
ransomNote
去验证这个数组是否包含了ransomNote
所需要的所有字母。
依然是数组在哈希法中的应用。
一些同学可能想,用数组干啥,都用
map
完事了,其实在本题的情况下,使用map
的空间消耗要比数组大一些的,因为map
要维护 红黑树 或者 哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了。 所以数组更加简单直接有效!
🍁代码:(Java、C++)
Java
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if(ransomNote.length() > magazine.length()) return false;
int[] mag = new int[26];
for(char c : magazine.toCharArray()){
mag[c - 'a']++;
}
for(char c : ransomNote.toCharArray()){
if(mag[c - 'a'] == 0) return false;
else mag[c - 'a']--;;
}
return true;
}
}
C++
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
if(ransomNote.size() > magazine.size()) return false;
vector<int> mag(26);
for(char c : magazine){
mag[c - 'a']++;
}
for(char c : ransomNote){
if(mag[c - 'a'] == 0) return false;
else mag[c - 'a']--;
}
return true;
}
};
🚀 运行结果:
🕔 复杂度分析:
-
时间复杂度: O ( m + n ) O(m + n) O(m+n),其中
m
是字符串ransomNote
的长度,n
是字符串magazine
的长度,我们只需要遍历两个字符一次即可。 -
空间复杂度: O ( ∣ S ∣ ) O(|S|) O(∣S∣),
S
是字符集,这道题中S
为全部小写英语字母,因此∣S∣= 26
。
题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!