赎金信

算法-赎金信

背景

题目

  • 给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。

    (题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)

    注意:

    你可以假设两个字符串均只含有小写字母。

    canConstruct(“a”, “b”) -> false
    canConstruct(“aa”, “ab”) -> false
    canConstruct(“aa”, “aab”) -> true

思路

  • 暴力枚举:俩层for循环
  • 哈希数组:使用哈希数组,先定义一个哈希数组int[26],遍历magazine字符串,在对应的下标增1,再遍历ransomNote字符串,在对应的数组下标减1,如果出现负数,表示false

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
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; //即对应的下标减一
}
for(int i : record){
if(i < 0){
return false;
}

}
return true;
}
}

总结

  • 核心思路:用数组代替哈希表统计字符频次(仅小写字母场景),先统计 magazine 的字符数,再扣除 ransomNote 所需字符数,最后检查是否有字符不足。

  • 关键转换:c - 'a' 将字符映射到数组下标,是处理小写字母计数的经典技巧。