知识拓展练习(经典面试题) / 39. 赎金信

一、题目

给你两个字符串: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 <= 10^5
ransomNote 和 magazine 由小写英文字母组成

四、参考题解

1、方法一:字符统计

题目要求使用字符串 magazine 中的字符来构建新的字符串 ransomNote,且ransomNote 中的每个字符只能使用一次,只需要满足字符串 magazine 中的每个英文字母 (’a’-’z’) 的统计次数都大于等于 ransomNote 中相同字母的统计次数即可。

如果字符串 magazine 的长度小于字符串 ransomNote 的长度,则我们可以肯定 magazine 无法构成 ransomNote,此时直接返回 false。

首先统计 magazine 中每个英文字母 a 的次数 cnt[a],再遍历统计 ransomNote 中每个英文字母的次数,如果发现 ransomNote 中存在某个英文字母 c 的统计次数大于 magazine 中该字母统计次数 cnt[c],则此时我们直接返回 false。

//Java
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;
  }
}

复杂度分析

时间复杂度:O(m+n),其中 m 是字符串 ransomNote 的长度,n 是字符串 magazine 的长度,我们只需要遍历两个字符一次即可。

空间复杂度:O(∣S∣),S 是字符集,这道题中 S 为全部小写英语字母,因此 ∣S∣=26。

知识拓展练习(经典面试题)