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.
(给定一任意字符串ransomNote和magazines字符串,实现一个函数,如果ransomNote字符串能够由magazines中所包含的字母构造,则返回true,否则返回false)
Each
letter
in
the
magazine
string
can
only
be
used
once
in
your
ransom
note.
(magazine字符串中的每个字母在ransomNote中只能使用一次)
Note:
You may assume that both strings contain only lowercase letters.(可以假设两个字串都是小写字母)
canConstruct(“a”, “b”) -> false
canConstruct(“aa”, “ab”) -> false
canConstruct(“aa”, “aab”) -> true
1.个人分析
统计ransomNote和magazine中每个字母的个数,如果ransomNote中的字母范围和数目都是magazine的子集,则结果返回true,否则就返回false。这里用元素个数为26的数组note[26]和mag[26]来保存各个字母的个数,字母a对应note[0],mag[0],字母b对应note[1],mag[1],依次类推。最后用note[i]<=mag[i]来判断结果。
2.个人解法
bool canConstruct(string ransomNote, string magazine)
{
char dict[26];
for (int i=0; i<26; ++i)
{
dict[i] = 'a' + i;
}
int note[26] = {0};
int mag[26] = {0};
string::iterator it;
for (it=ransomNote.begin(); it != ransomNote.end(); ++it)
{
for (int i=0; i<26; ++i)
{
if(*it == dict[i])
++note[i];
}
}
for (it=magazine.begin(); it != magazine.end(); ++it)
{
for (int i=0; i<26; ++i)
{
if(*it == dict[i])
++mag[i];
}
}
for(int i=0; i<26; ++i)
{
if(note[i] > mag[i])
return false;
}
return true;
}
结果显示自己的实现方法是正确的,而且时间复杂度为O(n),空间复杂度为O(1),唯一的不足是逻辑比较复杂,运行时间也比较慢。
3.参考解决方法
bool canConstruct(string ransomNote, string magazine)
{
int noteLen = ransomNote.length();
int magLen = magazine.length();
int noteCount[26] = {0};
int magCount[26] = {0};
if(noteLen > magLen)
return false;
if(noteLen == magLen && ransomNote != magazine)
return false;
if(noteLen == magLen && ransomNote == magazine)
return true;
for (int i=0; i<noteLen; ++i)
{
++noteCount[ransomNote[i] - 'a'];
}
for (int i=0; i<magLen; ++i)
{
++magCount[magazine[i] - 'a'];
}
for (int i=0; i<26; ++i)
{
if(noteCount[i] > magCount[i])
return false;
}
return true;
}
这种方法与自己的方法基本是一致的,但进行了局部优化和简化,在统计两字符串中的字母数时使用了一个技巧,即ransomNote[i] - ‘a’和magazine[i] - ‘a’作为字母的对应下标,这就省去了额外与26个字母进行比较的过程,结果显示效率比上一种方法提高了三倍多。
PS:
- 题目的中文翻译是本人所作,如有偏差敬请指正。
- 其中的“个人分析”和“个人解法”均是本人最初的想法和做法,不一定是对的,只是作为一个对照和记录。