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 <= ransomNote.length, magazine.length <= 105
-
ransomNote
和magazine
由小写英文字母组成
思考:
本题又是一道经典的利用哈希表进行求解的问题,通过哈希表存储第一个字符串中所含的元素,与第二个字符串相对比,进而判断真假。
值得注意的是,本题字符串都由小写字母组成,所以使用数组型哈希表也十分适合。而由于字母存在重复的情况,所以不能使用set型哈希表。
map型哈希表:
通过第一次for循环遍历magzine,更新哈希表,第二次for循环遍历ransomNote,再次更新哈希表,通过value值是否大于0来判断是否符合要求。
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
unordered_map<int, int> um;
//提前排除特殊情况
if (ransomNote.size() > magazine.size()) {
return false;
}
//遍历magazine
for (int i = 0; i < magazine.length(); i++) {
um[magazine[i] - 'a'] ++;
}
//遍历ransomNote
for (int i = 0; i < ransomNote.length(); i++) {
um[ransomNote[i] - 'a'] --;
//判断是否为负
if (um[ransomNote[i] - 'a'] < 0) {
return false;
}
}
return true;
}
};
数组型哈希表:
同理,我们可以使用数组型哈希表(因为只存在26个小写字母),定义一个含有26个元素的数组。
class Solution2 {
public:
bool canConstruct(string ransomNote, string magazine) {
int record[26] = { 0 };
//add
if (ransomNote.size() > magazine.size()) {
return false;
}
for (int i = 0; i < magazine.length(); i++) {
record[magazine[i] - 'a'] ++;
}
for (int j = 0; j < ransomNote.length(); j++) {
record[ransomNote[j] - 'a']--;
if (record[ransomNote[j] - 'a'] < 0) {
return false;
}
}
return true;
}
};
暴力求解:
当然,暴力求解法经久不衰。通过两层for循环,将所有元素都遍历一遍。
//暴力解法
class Solution3 {
public:
bool canConstruct(string ransomNote, string magazine) {
for (int i = 0; i < magazine.length(); i++) {
for (int j = 0; j < ransomNote.length(); j++) {
// 在ransomNote中找到和magazine相同的字符
if (magazine[i] == ransomNote[j]) {
ransomNote.erase(ransomNote.begin() + j); // ransomNote删除这个字符
break;
}
}
}
// 如果ransomNote为空,则说明magazine的字符可以组成ransomNote
if (ransomNote.length() == 0) {
return true;
}
return false;
}
};
参考:
代码随想录
往期回顾:
LeetCode454. 四数相加 II
LeetCode1. 两数之和
LeetCode202. 快乐数
LeetCode350. 两个数组的交集 II
LeetCode349. 两个数组的交集
LeetCode1002. 查找共用字符