LeetCode 383. Ransom Note 解题报告
题目描述
Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false.
示例
You may assume that both strings contain only lowercase letters.
canConstruct(“a”, “b”) -> false
canConstruct(“aa”, “ab”) -> false
canConstruct(“aa”, “aab”) -> true
限制条件
Each letter in the magazine string can only be used once in your ransom note.
解题思路
我的思路:
这道题目很简单,有多种解法。
首先讲一下我自己的解法,思路是把managzine分成两部分,已使用的字符(放在数组尾部)跟未使用的字符,初始时已使用的字符数是0。对于ransomNote字符串中的每一个字符,都在magazine中寻找相同的字符,如果找到,则将该字符放到magazine的尾部,如果没有找到,则直接返回false,如果ransomNote的所有字符都被找到,则返回true。这种算法的优点是不用额外申请空间,缺点是时间复杂度为O(n*m)。
其它思路:
由于题目说了只包含小写字母,所以充分利用这一点,建立一个标识26个字母数目的数组,遍历magazine,记录每个字母的数目,然后再次遍历ransomNote,减去出现的字母的数目,如果某个字母的数目小于0了,则返回false,如果所有字母都不小于0,则返回true。
这种算法有很多种实现方式,用vector,用map或是set都可以,下面我给出的实现是只用最简单的数组的。它的优点是时间复杂度为O(n+m),缺点是使用了额外的空间。
代码
我的代码
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
for (int i = 0; i < ransomNote.length(); i++) {
int remainLetters = magazine.length() - i;
int j = 0;
for (; j < remainLetters; j++) {
if (ransomNote[i] == magazine[j]) {
swap(magazine[j], magazine[remainLetters - 1]);
break;
}
}
if (j == remainLetters) {
return false;
}
}
return true;
}
};
其它代码
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int letters[26] = {0};
for (auto c: magazine) {
letters[c - 'a']++;
}
for (auto c: ransomNote) {
if (--letters[c - 'a'] < 0)
return false;
}
return true;
}
};
总结
今天做的这道题关于字符串匹配,感觉有关字符串的题目,都很讲究解法的灵活性,多做多积累吧。
明天继续填坑,努力加油!