给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
注意:
你可以假设两个字符串均只含有小写字母。
canConstruct(“a”, “b”) -> false
canConstruct(“aa”, “ab”) -> false
canConstruct(“aa”, “aab”) -> true
一开始想到的是用map来做
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int ranslength = ransomNote.length();
int maglength = magazine.length();
Map<Character,Integer> count = new HashMap();
for(int i = 0;i < ranslength;i++){
char s = ransomNote.charAt(i);
count.put(s,count.getOrDefault(s,0)+1);
}
for(int i = 0;i < maglength;i++){
char s = magazine.charAt(i);
if(count.get(s) == null){
continue;
}else{
count.put(s,count.get(s)-1);
}
}
for(int i = 0;i < ranslength;i++){
char s = ransomNote.charAt(i);
if(count.get(s)>0){return false;}
}
return true;
}
}
尽管做出来了,但是时间复杂度并不理想,于是翻越了评论大哥的解法
解题思路
第一个字符串长度大于第二个,直接返回false
统计每个字符串字符数量
第一个字符串任意一个字符的数目大于了第二个字符串该字符数量,返回false
最后返回true
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
char[] chars1 = ransomNote.toCharArray();
char[] chars2 = magazine.toCharArray();
if (chars1.length > chars2.length) {
return false;
}
int[] rans = new int[26];
int[] maga = new int[26];
for (char c : chars1) {
rans[c - 'a']++;
}
for (char c : chars2) {
maga[c - 'a']++;
}
for (int i = 0; i < rans.length ; i++) {
if (rans[i] > maga[i]) {
return false;
}
}
return true;
}
}
作者:wang-xue-lei-2
链接:https://leetcode-cn.com/problems/ransom-note/solution/2ms94yong-shu-zu-tong-ji-zi-fu-shu-mu-by-5dg8/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这种写法其实就是定义了一个数组作为“字典”,数组的角标就对应字母,数组的内容就代表该字母出现的次数,很精妙。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/ransom-note
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。