题目
给你两个字符串: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
由小写英文字母组成
解题思路
利用hash散列统计两个字符串中各个小写字母的出现次数,进行比较输出结果。
代码
方法一:分别统计两个字符串字母出现次数再比较
时间复杂度:O(magazine.length()+26),取决于magazine
字符串的长度
空间复杂度:O(1) (其实是O(26)*2 + 单独的变量占用的常量空间)
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int t1 = ransomNote.length();
int t2 = magazine.length();
int []hash1 = new int[26];//记录ransomNote各个小写字母的出现次数
int []hash2 = new int[26];//记录magazine各个小写字母的出现次数
if (t2<t1) //字母个数不够,肯定无法组成
return false;
else {
int i;
for (i = 0;i<t1;i++) {
hash1[ransomNote.charAt(i)-97]++; //ASCII转换成下标
hash2[magazine.charAt(i)-97]++;
}
for (i=i;i<t2;i++) //把magazine字符串里面没有统计的字符统计一遍
hash2[magazine.charAt(i)-97]++;
for (i=0;i<26;i++) //比较两个hash散列中私募出现的次数
if (hash1[i]>hash2[i])
return false;
return true;
}
}
}
方法二:用magazine
字符串字母次数抵消ransomNote
字符串字母次数
时间复杂度:O(magazine.length()+26),取决于magazine
字符串的长度
空间复杂度:O(1) (其实是O(26) + 单独的变量占用的常量空间) (略少于方法1)
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int t1 = ransomNote.length();
int t2 = magazine.length();
int []hash1 = new int[26];//记录ransomNote各个小写字母的出现次数
if (t2<t1) //字母个数不够,肯定无法组成
return false;
else {
int i;
for (i = 0;i<t1;i++) {
hash1[ransomNote.charAt(i)-97]++; //ASCII转换成下标
hash1[magazine.charAt(i)-97]--;
}
for (i=i;i<t2;i++) //把magazine字符串里面没有统计的字符统计一遍
hash1[magazine.charAt(i)-97]--;
for (i=0;i<26;i++) //比较两个hash散列中私募出现的次数
if (hash1[i]>0) //说明magazine中这个字母少了
return false;
return true;
}
}
}