leetcode刷题日记——赎金信
[ 题目描述 ]:
[ 思路 ]:
- 题目要求判断 ransomNote 能不能由 magazine 里面的字符构成,并且 magazine 中的字符只能使用一次
- 遍历 ransomNote 中的每个字符,如果其在 magazine 中能找到,则把找到的这个字符设置为不能使用,然后再去判断 ransomNote 中的下一个字符
- 运行如下
bool canConstruct(char* ransomNote, char* magazine) {
int m_len=strlen(magazine),r_len=strlen(ransomNote);
int* nums=(int*)malloc(sizeof(int)*m_len);
for(int i=0;i<m_len;i++){
nums[i]=0;
}
for(int i=0;i<r_len;i++){
int j=0;
for(j;j<m_len;j++){
if(ransomNote[i]==magazine[j] && nums[j]==0){
nums[j]=1;
break;
}
}
if(j==m_len) return false;
}
return true;
}
- 时间复杂度O(nm),空间复杂度O(M)
[ 优化 ]:
- 由于两个字符串都是小写英文字母组成,而字母只有26个
- 那么可以先统计 magazine 中各个字母的个数,然后遍历 ransomNote,每使用一个字母,则对那个字母的总数-1,如果该字母剩余数<0,则说明不能构成
- 运行如下
bool canConstruct(char* ransomNote, char* magazine) {
int m_len=strlen(magazine),r_len=strlen(ransomNote);
int nums[26]={0};
for(int i=0;i<m_len;i++){
nums[magazine[i]-'a']++;
}
for(int i=0;i<r_len;i++){
nums[ransomNote[i]-'a']--;
if(nums[ransomNote[i]-'a']<0) return false;
}
return true;
}
- 时间复杂度O(n),空间复杂度O(1)
[ 官方题解 ]:
- 一、字符统计,即优化思路;时间复杂度:O(m+n),其中 m 是字符串 ransomNote 的长度,n 是字符串 magazine 的长度,我们只需要遍历两个字符一次即可。空间复杂度:O(∣S∣),S 是字符集,这道题中 S 为全部小写英语字母,因此 ∣S∣=26