算法练习-赎金信(思路+流程图+代码)

news2024/12/23 20:58:45

难度参考

        难度:中等

        分类:哈希表

        难度与分类由我所参与的培训课程提供,但需要注意的是,难度与分类仅供参考。且所在课程未提供测试平台,故实现代码主要为自行测试的那种,以下内容均为个人笔记,旨在督促自己认真学习。

题目

        给你两个字符串:ransomNote 和 magazine,判断ransomNote 能不能由magazine 里面的字符构成。如果可以,返回true;否则返回false

        示例1:

        输入:ransomNote ="a", magazine = "b"输出:false

        示例2:

        输入: ransomNote = "aa", magazine ="ab"输出:false

        额外提示:

        1 <= ransomNote.length, magazine.length <= 10(5)

        ransomNote和magazine由小写英文字母组成

        magazine中的每个字符只能在ransomNote中使用一次

思路

        为了确认能否从 magazine 字符串中得到 ransomNote 字符串所需的所有字符,我们必须比较这两个字符串中各字符的出现次数。这可以通过以下步骤实现:

  1. 统计 magazine 中字符的频率
    创建一个大小为 26 的数组或向量用以表示每个字母的计数器,因为假设字符串仅包含小写字母。遍历 magazine 并增加每个字符相对应的计数器。

  2. 检查 ransomNote 的字符
    遍历 ransomNote,对于每个字符,减少其在计数器数组中对应的值。如果在减少之前某个字符的计数器值已经是 0,说明 magazine 中没有足够的字符以形成 ransomNote

  3. 结果判断
    如果所有字符在减少计数器时都没有产生负值,即 magazine 含有足够的每个字符以构建 ransomNote,则返回 true。否则,如果任何字符的计数器值变为负,说明 magazine 中缺乏足够的该字符,无法构建 ransomNote,返回 false。

示例

        假设我们有以下两个字符串:

        ransomNote: “aab”
        magazine: “baa”

        我们想要检查是否可以从杂志字符串 “magazine” 中剪下字母构造出勒索信 “ransomNote”。我们的方法是按照字母计数来检查。以下是对应的步骤和发生的事情:

  1. 初始化字符计数:

    我们创建了一个大小为 26 的数组或向量 charCount 来记录每个字母的出现次数。因为我们只处理小写字母,所以我们不需要更大的大小。每个位置初始化为 0。

  2. 统计 magazine 中的字符:

    对于字符串 “baa”,我们执行以下操作:

    • ‘b’ -> charCount['b' - 'a'](即 charCount[1])将从 0 变成 1。
    • ‘a’ -> charCount['a' - 'a'](即 charCount[0])将从 0 变成 1。
    • 另一个 ‘a’ -> charCount[0] 将从 1 变成 2。

    charCount 向量现在包含:[2, 1, 0, 0, …, 0],因为 ‘a’ 出现了两次,‘b’ 出现了一次,其他字母出现了零次。

  3. 检查 ransomNote 中的字符:

    对于字符串 “aab”,我们执行以下操作:

    • ‘a’ -> charCount[0] 从 2 减到 1。
    • 另一个 ‘a’ -> charCount[0] 从 1 减到 0。
    • ‘b’ -> charCount[1] 从 1 减到 0。

    在这个过程中,charCount 向量的每个相关位置至少为 0,这意味着 magazine 中每个所需字符的数量都足够 ransomNote 使用。

  4. 返回结果:

    由于 charCount 中没有任何索引变为负数,我们可以得出结论,在 magazine 中总是有足够的每个字符来构建 ransomNote,因此函数返回 true。

这就是代码的基本工作原理。通过遍历 ‘magazine’ 增加计数,然后遍历 ‘ransomNote’ 减少计数,最后根据计数结果决定是否可以构建出 ‘ransomNote’。

梳理

        这种方法之所以能够实现,是因为我们在检查能否从 `magazine` 得到 `ransomNote` 所需的所有字符时,遵循了两个基本原则:

        1. 频率匹配原则:
   每个字符在 `ransomNote` 中出现的频率不能高于在 `magazine` 中出现的频率。如果 `ransomNote` 需要比 `magazine` 提供更多的某个字符,这显然是不可能的,因为你不能从 `magazine` 中得到比它本身更多的某个字符。

        2. 字符独立原则:
   字符的使用是独立的。即,一个 'a' 的出现与另一个 'a' 的出现无关,它们可以独立计算。这使得我们可以通过简单地计数每个字符来跟踪 `magazine` 中有多少个 'a',而不必关心它们在字符串中的位置或顺序。

        当我们使用一个大小为 26 的数组(针对 26 个小写字母)来统计 `magazine` 中各字母的出现次数时,我们就执行了一个由字符到频率的映射。由于 `ransomNote` 可能包含重复的字母,通过逐个检查并递减 `magazine` 中的相应字母计数,我们实际上是在确认是否对于 `ransomNote` 中的每个字符,`magazine` 都至少有相等数量的该字符。

        这个检查过程中,如果发现某个字符在 `magazine` 中的计数已经为零(即已经被 'ransomNote' 用尽),然后 `ransomNote` 还需要该字符,那么说明 `magazine` 不能满足 `ransomNote` 的需求。

        因为这种方法直接通过频率匹配来确定是否可行,所以它是高效且有效的。它不必关心两个字符串的任何其他复杂关系,如它们的子序列关系或排序。当我们完成了遍历整个 `ransomNote` 名称,并且没有发现任何计数不足以匹配需求的情况时,我们就可以确定 `magazine` 可以提供足够的字符来构建 `ransomNote`。

代码

#include <iostream> // 包含输入/输出流库
#include <vector>   // 包含 vector 容器库
#include <string>   // 包含 string 类库
using namespace std; // 使用 std 命名空间,避免 std:: 前缀

// 函数 canConstruct 用于判断是否能够通过 magazine 的字母构造出 ransomNote
bool canConstruct(string ransomNote, string magazine) {
    vector<int> charCount(26, 0); // 创建一个大小为 26 的整数向量,用于计数每个字符的出现次数,初始化为 0

    for (char ch : magazine) { // 遍历 magazine 中的每个字符
        ++charCount[ch - 'a']; // 增加 magazine 中当前字符的计数
    }

    for (char ch : ransomNote) { // 遍历 ransomNote 中的每个字符
        if (--charCount[ch - 'a'] < 0) { // 减少 ransomNote 中当前字符的计数,如果计数小于 0 则返回 false
            return false;
        }
    }

    return true; // 如果 ransomNote 中的所有字符都能在 magazine 中找到,则返回 true
}

int main() {
    string ransomNote1 = "a"; // 初始化测试用例 1 的 ransomNote  
    string magazine1 = "b";   // 初始化测试用例 1 的 magazine
    // 输出测试结果:使用可以构造的函数结果,并转换为 "true" 或 "false" 字符串
    cout << (canConstruct(ransomNote1, magazine1) ? "true" : "false") << endl;
    
    string ransomNote2 = "aa"; // 初始化测试用例 2 的 ransomNote
    string magazine2 = "ab";   // 初始化测试用例 2 的 magazine
    // 输出测试结果:使用可以构造的函数结果,并转换为 "true" 或 "false" 字符串
    cout << (canConstruct(ransomNote2, magazine2) ? "true" : "false") << endl;

    return 0; // main 函数正常终止
}

        事实上还可以在开始前判断一下长度,长度不同直接否决,这边没写。

        时间复杂度:O(n)

        空间复杂度:O(1)

打卡

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1452995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Excel TEXT函数格式化日期

一. 基本语法 ⏹Excel 的 TEXT 函数用于将数值或日期格式化为指定的文本格式 TEXT(value, format_text)二. 拼接路径案例 # 将当前单元格日期格式化 "ls -ld /data/jmw/01/"&TEXT(A2,"YYYYMMDD")&""# 此处的日期, 是名称管理器里面定…

自然语言编程系列(四):GPT-4对编程开发的支持

在编程开发领域&#xff0c;GPT-4凭借其强大的自然语言理解和代码生成能力&#xff0c;能够深刻理解开发者的意图&#xff0c;并基于这些需求提供精准的编程指导和解决方案。对于开发者来说&#xff0c;GPT-4能够在代码片段生成、算法思路设计、模块构建和原型实现等方面给予开…

JAVA面试题基础篇

1. 二分查找 要求 能够用自己语言描述二分查找算法 能够手写二分查找代码 能够解答一些变化后的考法 算法描述 前提&#xff1a;有已排序数组 A&#xff08;假设已经做好&#xff09; 定义左边界 L、右边界 R&#xff0c;确定搜索范围&#xff0c;循环执行二分查找&#…

基于Arduino UNO设计一个温控制系统

目录 概述 1 硬件结构 1.1 整体硬件介绍 1.2 硬件连接结构 2 软件设计 2.1 软件功能介绍 2.2 关于Arduino的一些知识点 2.2.1 定时器 2.2.2 PWM 2.3 代码实现 2.3.1 编译工具 2.3.2 详细代码 3 测试 3.1 温度数据监控 3.2 温控测试 概述 本文介绍如何使用Ardui…

精通C语言:打造高效便捷的通讯录管理系统

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言项目 贝蒂的主页&#xff1a;Betty‘s blog 引言 在我们大致学习完C语言之后&#xff0c;我们就可以利用目前所学的知识去…

MATLAB环境下使用二维高分辨时频分析方法提取波状分量

MATLAB环境下使用二维高分辨时频分析方法提取波状分量&#xff08;分离混合地震数据&#xff09;。 为了得到更高的时频分辨率&#xff0c;近年来涌现出了大量的新的时频分析方法。有些以线性和非线性时频分析为基础&#xff0c;有些则另辟蹊径&#xff0c;比如Hilbert-Huang变…

2.12日学习打卡----初学RocketMQ(三)

2.12日学习打卡 目录&#xff1a; 2.12日学习打卡一. RocketMQ高级特性&#xff08;续&#xff09;消息重试延迟消息消息查询 二.RocketMQ应用实战生产端发送同步消息发送异步消息单向发送消息顺序发送消息消费顺序消息全局顺序消息延迟消息事务消息消息查询 一. RocketMQ高级特…

Packet Tracer - Configuring ASA Basic Settings and Firewall Using CLI

Packet Tracer - 使用CLI配置ASA基本设置和防火墙 IP地址表 目标 验证连接并探索ASA设备使用CLI配置ASA的基本设置和接口安全级别使用CLI配置路由、地址转换和检查策略配置DHCP、AAA和SSH服务配置DMZ区域、静态NAT和访问控制列表&#xff08;ACL&#xff09; 场景 您的公司…

grafana配置钉钉告警模版(一)

1、配置钉钉告警模版 创建钉钉告警模版&#xff0c;然后在创建钉钉告警时调用模版。 定义发送内容具体代码 my_text_alert_list 是模版名称后面再配置钉钉告警时需要调用。 {{/* 定义消息体片段 */}} {{ define "my_text_alert_list" }}{{ range . }}告警名称&…

redis为什么使用跳跃表而不是树

Redis中支持五种数据类型中有序集合Sorted Set的底层数据结构使用的跳跃表&#xff0c;为何不使用其他的如平衡二叉树、b树等数据结构呢&#xff1f; 1&#xff0c;redis的设计目标、性能需求&#xff1a; redis是高性能的非关系型&#xff08;NoSQL&#xff09;内存键值数据…

在Postgresql 下安装QGIS

安装QGIS的前提是需要 在windows下安装Postgres&#xff0c;具体可以参考文章&#xff1a; Windows 安装和连接使用 PgSql数据库 安装GIS的具体步骤如下&#xff1a; 一.打开 Application Stack Builder 二.选择默认端口和安装目标 三.选择【Spatial Extensions】 四.选择安装…

链式结构实现队列

链式结构实现队列 1.队列1.1队列的概念及结构1.2队列的实现 2. 队列的各种函数实现3. 队列的全部代码实现 1.队列 1.1队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(Fi…

【大厂AI课学习笔记】【2.1 人工智能项目开发规划与目标】(5)数据管理

今天学习了数据管理&#xff0c;以及数据管理和数据治理的区别和联系。 数据管理&#xff1a;利用计算机硬件和软件技术对数据进行有效的收集、存储、处理和应用的过程其目的在于充分有效地发挥数据的作用。 实现数据有效管理的关键是数据组织。 数据管理和数据治理的区别&am…

无人驾驶控制算法LQR和MPC的仿真实现

1. LQR控制器 1.1 问题陈述 考虑一个质量为 m m m 的滑块在光滑的一维地面上运动。初始时&#xff0c;滑块的位置和速度均为 0 0 0。我们的目标是设计一个控制器&#xff0c;基于传感器测得的滑块位置 x x x&#xff0c;为滑块提供外力 u u u&#xff0c;使其能够跟随参考…

每日一题——LeetCode1455.检查单词是否为句中其他单词的前缀

方法一 js函数slice() 将字符串按空格符分割为单词数组&#xff0c;记searchWord的长度为n&#xff0c;分割每个单词的前n位看是否和searchWord匹配 var isPrefixOfWord function(sentence, searchWord) {let res sentence.split(" ")for(i 0 ; i < res.lengt…

七天入门大模型 :大模型LLM 训练理论和实战最强总结!

本文对于想入门大模型、面试大模型岗位、大模型实具有很强的指导意义。喜欢记得收藏、关注、点赞 文章目录 技术交流群用通俗易懂方式讲解系列总览介绍预训练范式如何确定自己的模型需要做什么训练&#xff1f;模型推理的一般过程PyTorch 框架设备PyTorch基本训练代码范例Trans…

【复现】cellinx摄像设备 未授权漏洞_50

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 cellinx是一家韩国的摄像设备 二 .漏洞影响 通过未授权访问可以创建用户进入后台&#xff0c;可能造成系统功能破坏。 三.漏洞复…

CCF编程能力等级认证GESP—C++8级—20231209

CCF编程能力等级认证GESP—C8级—20231209 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)奖品分配大量的工作沟通 答案及解析单选题判断题编程题1编程题2…

GIS利用不舒适指数绘制地区的生物气候舒适度图

生物气候舒适度定义了最适宜的气候条件,在这种条件下,人们感到健康和充满活力。生物气候舒适度地图对城市规划研究特别有用。温度、相对湿度和风速等要素对评估生物气候舒适度非常重要。[1] 人们已经得出了许多不同的指数来确定生物气候舒适度。在本博文中,我们将使用广泛使…

基于SringBoot+Vue的大学生社团管理系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 1.1 研究背景 1.…