C++算法练习-day17——383.赎金信

题目来源:. - 力扣(LeetCode)

题目思路分析

题目要求我们判断给定的 ransomNote 字符串是否可以通过从 magazine 字符串中选取字符来构造。字符可以从 magazine 中重复选取,但每个字符只能使用一次。这是一个典型的字符计数问题,我们可以通过统计 magazine 中每个字符的出现次数,然后依次减去 ransomNote 中对应字符的需求次数来判断是否能够满足构造要求。

思路实现步骤

  1. 边界条件检查:首先,如果 ransomNote 的长度大于 magazine 的长度,那么显然无法从 magazine 中选取足够的字符来构造 ransomNote,直接返回 false

  2. 字符计数:创建一个长度为 26 的整数数组(或向量),用于记录 magazine 中每个小写英文字母('a' 到 'z')的出现次数。遍历 magazine,对每个字符进行计数。

  3. 字符需求检查:遍历 ransomNote,对每个字符的需求次数进行扣除(即在计数数组中对应位置减 1)。如果某个字符的需求次数超过了 magazine 中的实际出现次数(即计数数组中的值变为负数),则返回 false

  4. 返回结果:如果成功遍历完 ransomNote 而没有返回 false,则说明可以从 magazine 中选取字符来构造 ransomNote,返回 true

代码:

#include   
#include   
  
class Solution {  
public:  
    bool canConstruct(string ransomNote, string magazine) {  
        // 如果ransomNote的长度大于magazine的长度,直接返回false  
        if (ransomNote.size() > magazine.size()) {  
            return false;  
        }  
          
        // 创建一个长度为26的向量,用于记录每个小写字母的出现次数  
        vector res(26, 0);  
          
        // 遍历magazine,对每个字符进行计数  
        for (char e : magazine) {  
            ++res[e - 'a']; // 将对应字符的计数加1  
        }  
          
        // 遍历ransomNote,对每个字符的需求次数进行扣除  
        for (char e : ransomNote) {  
            --res[e - 'a']; // 将对应字符的计数减1  
              
            // 如果某个字符的需求次数超过了magazine中的实际出现次数,返回false  
            if (res[e - 'a'] < 0) {  
                return false;  
            }  
        }  
          
        // 如果成功遍历完ransomNote而没有返回false,则返回true  
        return true;  
    }  
};

知识点摘要

  1. 字符计数:在处理字符相关的问题时,可以通过创建一个固定大小的数组(或向量)来记录每个字符的出现次数。这种方法在处理只包含有限字符集(如小写英文字母)的问题时特别有效。

  2. 边界条件检查:在算法实现中,对输入进行边界条件检查是一个好习惯。这可以避免一些不必要的错误,并提高代码的健壮性。

  3. 线性扫描:通过线性扫描字符串来统计字符出现次数或检查字符需求,是一种简单而有效的算法技巧。这种方法的时间复杂度通常为 O(n),其中 n 是字符串的长度。

本题通过字符计数的方法,高效地解决了判断一个字符串是否可以通过从另一个字符串中选取字符来构造的问题。这种方法的关键在于利用一个固定大小的数组(或向量)来记录字符的出现次数,并通过线性扫描来统计和检查字符。这种方法不仅适用于本题,还可以推广到类似的字符计数和字符匹配问题中。通过学习和掌握这种方法,我们可以更高效地解决一些字符相关的算法问题。

你可能感兴趣的:(C++算法练习,c++,开发语言,1024程序员节)