开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 21 天,点击查看活动详情
383. 赎金信
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
注意:
你可以假设两个字符串均只含有小写字母。
canConstruct("a", "b") -> false
canConstruct("aa", "ab") -> false
canConstruct("aa", "aab") -> true
第一遍理解错题目意思了,直接无脑HashSet,发现写完后会报错,然后我就返回去又看了一遍题目,这才知道有重复的,而刚才我用HashSet直接就去重了,这才导致错误,但是这道题这样看是可以用Map来做的,但是呢,Map要用到红黑树,耗时就比较大,所以最优解还是用数组。同时也发现set需要用封装类而不能用原始类型,于是积累了一下。
Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。
原始类型 | 封装类 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
思路
这道题真正读懂后,发现他和有效字母异位词有点类似,直接用数组哈希表就可以了,先创建一个长度为26的数组,让magazine中的每个字母都存入数量,在让ransomNote中的字母在数组中减去对应数量,最后如果有负数存在,说明就不可以。
代码
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] res=new int[26];
for(char c:magazine.toCharArray()){
res[c-'a']++;
}
for(char c:ransomNote.toCharArray()){
res[c-'a']--;
}
for(int i:res){
if(i<0) return false;
}
return true;
}
}