Leetcode 383 赎金信
赎金信(Ransom Not)
给定一个赎金信 (ransom
) 字符串和一个杂志(magazine
)字符串,判断第一个字符串 ransom
能不能由第二个字符串 magazines
里面的字符构成。如果可以构成,返回 true
;否则返回 false
。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
示例 1:
输入:ransomNote = "a", magazine = "b"
输出:false
示例 2:
输入:ransomNote = "aa", magazine = "ab"
输出:false
示例 3:
输入:ransomNote = "aa", magazine = "aab"
输出:true
提示:
- 你可以假设两个字符串均只含有小写字母。
bool canConstruct(char * ransomNote, char * magazine){
int ransomNoteSize = strlen(ransomNote);
int magazineSize = strlen(magazine);
for(int i =0;i< ransomNoteSize; i++){
bool isFound = false;
for(int j = 0; j < magazineSize; j++) {
if(magazine[j] == ransomNote[i]) {
isFound = true;
magazine[j] = '-';
break;
}
}
if (!isFound){
return false;
}
}
return true;
}
找到一个把报纸上的nage 字母挖掉
另一种思路,看看报纸上的内容可不可以组成想要的内容
bool canConstruct(char * ransomNote, char * magazine){
int ransomNoteSize = strlen(ransomNote);
int magazineSize = strlen(magazine);
for(int i =0;i< ransomNoteSize; i++){
bool isFound = false;
for(int j = i; j < magazineSize; j++) {
if(magazine[j] == ransomNote[i]) {
isFound = true;
char temp = magazine[j];
magazine[j] = magazine[i];
magazine[i] =temp;
break;
}
}
if (!isFound){
return false;
}
}
return true;
}
bool canConstruct(char * ransomNote, char * magazine){
int ransomNoteSize = strlen(ransomNote);
int magazineSize = strlen(magazine);
// 这个字符在左边出现的次数小于在右边出现的次数
for(int i =0;i< ransomNoteSize; i++){
int countRansomNote = 0;
for (int j = 0; j< ransomNoteSize; j++){
if(magazine[j] == ransomNote[i]){
countRansomNote++;
}
}
int countMagazine = 0;
for (int j =0; j< magazineSize; j++){
if(magazine[j] == ransomNote[i]){
countMagazine++;
}
}
if (countRansomNote > countMagazine){
return false;
}
}
return true;
}
但是这时候还是有O(n^2) 的时间复杂度,这时候大家可能已经可以想到 O(n) 的解法了
bool canConstruct(char * ransomNote, char * magazine){
int ransomNoteSize = strlen(ransomNote);
int magazineSize = strlen(magazine);
// 这个字符在左边出现的次数小于在右边出现的次数
int countRansomNote['z'-'a'+1] = {0};
for (int i =0; i < ransomNoteSize; i++){
countRansomNote[ransomNote[i]-'a']++;
}
int countMagazine['z'-'a'+1] = {0};
for (int i =0; i < magazineSize; i++){
countMagazine[magazine[i]-'a']++;
}
for(int i=0; i<26;i++){
if (countRansomNote[i]> countMagazine[i]) return false;
}
return true;
}
甚至我们只要一个数组就可以了
bool canConstruct(char * ransomNote, char * magazine){
int ransomNoteSize = strlen(ransomNote);
int magazineSize = strlen(magazine);
// 这个字符在左边出现的次数小于在右边出现的次数
int countDiff['z'-'a'+1] = {0};
for (int i =0; i < ransomNoteSize; i++){
countDiff[ransomNote[i]-'a']++;
}
for (int i =0; i < magazineSize; i++){
countDiff[magazine[i]-'a']--;
}
for(int i=0; i<26;i++){
if (countDiff[i]>0) return false;
}
return true;
}
也可以排完序后来比比看