摘要:
Leetcode的AC指南 —— 哈希法:383. 赎金信。题目介绍:给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。如果可以,返回 true ;否则返回 false 。magazine 中的每个字符只能在 ransomNote 中使用一次。
一、题目
题目介绍:
给你两个字符串: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 由小写英文字母组成
二、解析
1、哈希法 —— map
public static boolean canConstruct(String ransomNote, String magazine) {
// key中magazine中的字符,value中统计每个字符出现的次数
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < magazine.length(); i++) {
char ch = magazine.charAt(i);
// 如果当前字符存在,对应的value值加1,如果当前值不存在,存入新的key和value(1)。
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
for (int i = 0; i < ransomNote.length(); i++) {
char ch = ransomNote.charAt(i);
// 如果当前字符存在,对应的value值减1,如果当前值不存在,存入新的key和value(-1)。
map.put(ch, map.getOrDefault(ch,0) - 1);
// 如果当前字符对应的value值小于0,则代表ransomNote不能由 magazine 里面的字符构成
if (map.get(ch) < 0) return false;
}
return true;
}
- 时间复杂度 O(n)
- 空间复杂度O(1)
2、哈希法 —— 数组
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
// shortcut
if (ransomNote.length() > magazine.length()) {
return false;
}
// 定义一个哈希映射数组
int[] record = new int[26];
// 遍历
for(char c : magazine.toCharArray()){
record[c - 'a'] += 1;
}
for(char c : ransomNote.toCharArray()){
record[c - 'a'] -= 1;
}
// 如果数组中存在负数,说明ransomNote字符串总存在magazine中没有的字符
for(int i : record){
if(i < 0){
return false;
}
}
return true;
}
}
- 时间复杂度: O(n)
- 空间复杂度: O(1)
三、总结
其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了。 所以数组更加简单直接有效!