题目
为了不在赎金信中暴露字迹,从杂志上搜索各个需要的字母,组成单词来表达意思。
给你一个赎金信 (ransomNote) 字符串和一个杂志(magazine)字符串,判断 ransomNote 能不能由 magazines 里面的字符构成。
如果可以构成,返回 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 由小写英文字母组成
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ra… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
- 就是说能不能由后面的字符串S2中的字符重组成前面的字符串S1
- 因为题目中说了每个字符只能使用一次,数量不够自然不能重组成功。所以S2的长度要大于等于S1的长度
- 在S2的长度大于等于S1长度的时候,因为每个字符只能使用一次,所以S1中包含的字符c,记c的个数为n,S2也需要包含c,且c的个数n2>=n
解题代码
第一次提交:
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if(magazine.length() < ransomNote.length()) return false;
HashMap<Character,Integer> map1 = new HashMap<>();
HashMap<Character,Integer> map2 = new HashMap<>();
char[] ran=ransomNote.toCharArray();
for(char c:ran)
{
map1.put(c,map1.getOrDefault(c,0)+1);
}
char[] maga=magazine.toCharArray();
for(char c:maga)
{
map2.put(c,map2.getOrDefault(c,0)+1);
}
for(char c:ran)
{
int n=map1.get(c);
int n2 = map2.getOrDefault(c,0);
if(n2 < n) return false;
}
return true;
}
}
第一次解题:我使用了HashMap这个数据结构去统计每个字符出现的个数,使用了两张hashmap表然后再进行比较的。耗时14ms
第二次解题: 官方解题方法:
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length())
{
return false;
}
int[] cnt = new int[26];
for (char c : magazine.toCharArray()) {
cnt[c - 'a']++;
}
for (char c : ransomNote.toCharArray()) {
cnt[c - 'a']--;
if(cnt[c - 'a'] < 0) {
return false;
}
return true;
}
}
官方题解则是由英文字母推出最多有26个字母这个信息。使用一个数组就可以完成。题目只需要true和false,有时需要根据结论去思考算法的过程。