383. 赎金信(力扣LeetCode)

文章目录

  • 383. 赎金信
    • 题目描述
    • 哈希表:数组
    • 暴力:字符串erase删除函数

383. 赎金信

题目描述

给你两个字符串: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 由小写英文字母组成

哈希表:数组

代码通过一个数组来统计magazine中每个字符出现的次数,然后对ransomNote中的每个字符递减对应的次数。最后,检查数组中是否有任何负值,负值意味着magazine中字符的数量不足以构成ransomNote,此时返回false。如果所有字符计数都不是负值,意味着可以构造出ransomNote,这时返回true。

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        // 初始化一个长度为26的数组来存储每个字符出现的次数,对应a-z
        int a[26] = {0};
        // 遍历杂志(magazine)字符串
        for(int i = 0; i < magazine.size(); i++)
            // 对于杂志中的每个字母,递增其在数组a中对应的计数
            // 'a' 的 ASCII 值被用作偏移量来确定数组中的位置
            a[magazine[i] - 'a']++;
        // 遍历赎金信(ransomNote)字符串
        for(int i = 0; i < ransomNote.size(); i++)
            // 对于赎金信中的每个字母,在数组a中对应的计数中递减
            // 如果杂志中有足够的字符用于赎金信,则此操作不会导致负数
            a[ransomNote[i] - 'a']--;
        // 再次遍历数组,检查是否有任意字符计数小于0
        for(int i = 0; i < 26; i++)
            // 如果发现某个字符的计数小于0,表示杂志中没有足够的该字符
            // 来满足赎金信的需要,因此返回false
            if(a[i] < 0)
                return false;
        // 如果所有字符的计数都不小于0,那么可以构造赎金信,返回true
        return true;
    }
};

暴力:字符串erase删除函数

解决方法是通过遍历magazine中的每一个字符,与ransomNote中的字符进行比较。如果找到相同的字符,则从ransomNote中移除这个字符,确保每个magazine中的字符只能用一次。这个过程会一直持续直到magazine遍历完成。如果最后ransomNote为空字符串,表明magazine中的字符足够组成ransomNote,返回true。否则返回false。

这段代码的时间复杂度较高,大约是O(m*n),其中m和n分别是magazine和ransomNote的长度。对于每个magazine中的字符,代码可能要遍历整个ransomNote字符串。在最坏的情况下(例如magazine和ransomNote都非常长且没有匹配字符)。

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        // 循环遍历 magazine 中的每一个字符
        for(int i = 0; i < magazine.size(); i++) {
            // 内嵌循环遍历 ransomNote 中的每一个字符
            for(int j = 0; j < ransomNote.size(); j++) {
                // 如果在 ransomNote 中找到了 magazine 的当前字符
                if(magazine[i] == ransomNote[j]) {
                    // 从 ransomNote 中删除找到的这个字符
                    // 这样做可以确保 magazine 中的每个字符只被使用一次
                    ransomNote.erase(ransomNote.begin() + j);
                    // 退出内循环,继续查找下一个 magazine 中的字符
                    break;
                }
            }
        }
        // 如果 ransomNote 为空字符串,说明 ransomNote 中的所有字符都在 magazine 中找到了
        // 因此可以构造赎金信,返回 true
        if(ransomNote == "")
            return true;
        // 否则,说明不能用 magazine 中的字符构造出 ransomNote,返回 false
        return false;
    }
};

你可能感兴趣的:(leetcode,leetcode,算法,c++,哈希算法)