【算法杂货铺】模拟

news2024/11/24 10:46:03


目录

🌈前言🌈

📁1576. 替换所有的问号​编辑

📁 495. 提莫攻击

📁 6. Z 字形变换

📁38. 外观数列

📁1419. 数青蛙

📁 总结


🌈前言🌈

        欢迎观看本期【算法杂货铺】,本期内容将讲解算法中的模拟,模拟算法就是将题目给用代码语言翻译出来,是一个非常简单的算法,重要的是看懂题目,以及翻译成代码,此外,画图注重细节也是很重要的。

        本篇文章注重讲解不同题目,从三个角度,带你从零开始理解模拟算法。

        1. 讲解多种习题的题目;2. 算法原理;3. 代码展示。

📁1576. 替换所有的问号

 📂 题目解析

        这是一套非常简单的题目,即将 ‘ ?’ 替换成前后不相等的小写字母即可。“?zs” 可以替换成,除“zzs”以外的任何字符串。

 📂 算法原理

        做模拟题目,重要的就是看懂题目,在此基础上,我们只要画图即可,将各种可能推演出来,翻译成代码即可。

        通过上图的展示,我们就将?所有可能出现的位置给枚举出来,现在我们只要保证每一种情况成立即可。

        纯模拟。从前往后遍历整个字符串,找到问号之后,就⽤ a ~ z 的每⼀个字符去尝试替换即 可。

 📂 代码展示 

class Solution {
public:
    string modifyString(string s) {
        for(int i=0;i<s.size();i++)
        {
            if(s[i] == '?')
            {
               for(char ch = 'a' ; ch <='z';ch++)
               {
                 /*

                 1)如果 i==0,只要保证s[i+1] != ch即可。
                 2)如果 i == size-1 , 只要保证 s[i-1] != ch即可。
                 3)若i在区间[1, size-2]中,则要保证 s[i-1] != ch && s[i+1] != ch

                 */
                 if((i==0 || s[i-1] != ch) && (i==s.size()-1 || s[i+1] != ch))
                 {
                     s[i] = ch;
                 }
               }
            }
        }
        return s;
    }
};

📁 495. 提莫攻击

 📂 题目解析

        别看题目这么长就害怕,其实非常好理解,就是给我们一个非递减的整数数组,第i个元素表示第i秒发动的攻击,会持续d秒。

        如果从第i秒开始,持续d秒,到i+d秒;如果第i+1秒受到攻击,则会从第i+1秒内重新计算,持续到第i+1+d秒,以此类推。

 📂 算法原理

        这道题,就是一道模拟+分类讨论的题目。对于模拟题来说,我们尽可能的画图,方便理解。

        我们首先来看示例1,第1秒和第4秒发起了攻击,其实这个在整个时间段内有1~5秒,第 t[i] 秒发动了攻击,加上d秒,不会影响到第 t[i+1] 秒,即得出公式,t[i] - t[i-1] >= d。

        这里为什么可以等于d呢,是因为是从第t[i]秒开始算起。

例如t = {1,3} ,d= 2

         3 - 1 >= 2,从第1秒到第2秒是持续的时间,不会影响到第3秒。

         当i到了最后攻击的时段时,我们只需要总秒数+d即可,因为最后一项后不会在攻击了,只会持续d秒了。

        因此我们得出两种结论,即t[ i ] - t[ i - 1] >= d 时,总秒数+d ; 遍历到数组最后一个位置时,总秒数 + d。

        画出示例2的图,我们便可知,t[ i ] - t [i - 1] < d时,总秒数加上 t[ i ] 到 t [i - 1]内持续的时间,即ret += t[ i ] - t[ i - 1]。

        以上,就是这道题目的所有情况,其实只要画出图来,一切就很清晰了。

 📂 代码展示 

class Solution {
public:
    int findPoisonedDuration(vector<int>& timeSeries, int duration) {
        int ret = 0;
        for(int i=1;i<timeSeries.size();i++)
        {
            int temp = timeSeries[i] - timeSeries[i-1];
            if(temp >= duration)
                ret += duration;
            else
                ret += temp;
        }
        return ret + duration;
    }
};

📁 6. Z 字形变换

 📂 题目解析

        其实通过题目,就可以看出模拟解法,通过一个矩阵,找出矩阵的规律,在一次遍历这个矩阵即可。

        但如果这个时间复杂度会是len*N,如果数据量较大,可能会报错。所以我们要进行优化。

        对于模拟算法来说,绝大多数的优化都是找规律,我们通过画图,找出矩阵的规律,即可。

 📂 算法原理

        通过画图,我们可以得出以下结论,由于篇幅限制,我们这里之以示例2为例,但以下结论适用于本题任何场景,当然如果numRows=0,则就是原字符串,需要特殊处理。

 📂 代码展示 

class Solution {
public:
    string convert(string s, int numRows) {
        int d = 2 * numRows - 2;
        int n = s.size();
        string ret;
        //特殊判断
        if(numRows == 1)
        {
            return s;
        }

        //处理第0行
        for(int i = 0;i < n;i += d)
        {
            ret += s[i];
        }

        //处理第1行 - 第n-2行
        for(int k = 1;k < numRows-1;k++)
        {
            for(int i= k,j=d-k;i<n||j<n;i+=d,j+=d)
            {
                if(i < n)
                    ret += s[i];
                if(j < n)
                    ret += s[j];
            }
        }

        //处理最后一行
        for(int i = numRows-1;i < n ; i += d)
        {
            ret += s[i];
        }
        return ret;
    }
};

📁38. 外观数列

 📂 题目解析

        画图可知,每一项都是由前一项翻译出来的,第一项为“1”,例如第2项是1个1得出来的,第3项是由第2项得出,即1个2和1个1。

        就是判断连续且相同的字符有多少个,添加到新字符串中。

 📂 算法原理

        这道题就是模拟+双指针的思路,如下图所示:

        当right遍历到字符串尾的时候,新字符串=“231231”

 📂 代码展示

class Solution {
public:
    string countAndSay(int n) {
        string ret = "1";
        //翻译n-1次
        for(int i=1;i<n;i++)
        {
            string temp;
            int len = ret.size();
            for(int right = 0,left =0;right < len;)
            {
                while(right < len && ret[right] == ret[left])
                    right++;
                temp += to_string(right - left) + ret[left];
                left = right;
            }
            ret = temp;
        }
        return ret;
    }
};

📁1419. 数青蛙

 📂 题目解析

        其中这个提示是比较总要的,所以单独放了出来。

        出现一次“crock”就代表了一声蛙鸣,代表有一只青蛙,题目要求返回最小的青蛙个数,所以两声“crock”最少可以有1只青蛙。如果不是字符“croak”不是有效组合,返回-1。

 📂 算法原理

        这里我们采用模拟+哈希的算法。

        如下图所示,以“croakcroak”为例子,当s[i]是c的时候,我们c索引对应的值++,碰见r的时候,c--,r++,直到遍历到k,此时代表有一只青蛙。k就代表着最少的青蛙个数

        遍历到第二个c的时候,因为求的最少的青蛙个数,k此时不为0,所以可以k--,c++。

        因此,可以得出以下结论:

        对于r,o,a,k 找一下前驱字符,判断是否为空,如果不是空,前驱字符--,当前字符++;否则返回-1。

        对于c来说,判断k是不是空,如果不是空,k--,c++;如果为空,c++。

 📂 代码展示

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        string t = "croak";
        int n = t.size();
        vector<int> hash(n); //模拟哈希

        unordered_map<char,int> index; //记录字符的下标
        for(int i=0;i<n;i++)
        {
            index[t[i]] = i;
        }

        for(auto ch : croakOfFrogs)
        {
            if(ch == 'c')
            {
                //检查k是否为空,即判断是否已有青蛙
                if(hash[n-1] != 0)
                    hash[n-1]--;
                hash[0]++;
            }
            else
            {
                int i = index[ch];
                if(hash[i-1] == 0)
                    return -1;
                hash[i-1]--;
                hash[i]++;
            }
        }

        //当遍历完数组后,k之前的字符必须为空,否则为无效字符
        for(int i=0;i<n-1;i++)
        {
            if(hash[i] != 0)
            {
                return -1;
            }
        }
        return hash[n-1];

    }
};

📁 总结

        以上就是对与模拟算法的基本讲解了,通过习题,我们知道基础的模拟题就是将题目翻译一遍,复杂的模拟题,通常和一些其他算法结合在一起。

        对于模拟算法的优化,通常是找规律等手段。日常在做模拟题的时候,通常是需要画图的,这样有助于我们找出规律,以及一些细节。

        以上就是本期【算法杂货铺】模拟算法的主要内容了,如果感觉对你有帮助,欢迎点赞,收藏,关注Thanks♪(・ω・)ノ

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

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

相关文章

Linux自动化任务管理以及常见定时命令示例

Linux以其强大的稳定性和灵活性成为了许多IT专业人士的首选。其中&#xff0c;自动化任务管理是Linux系统管理不可或缺的一部分&#xff0c;它能帮助系统管理员有效地管理系统任务&#xff0c;提高工作效率。定时任务&#xff0c;作为自动化任务管理的重要组成部分&#xff0c;…

如何在IDEA 中设置背景图片

在IDEA 中设置背景图片&#xff0c;可以按照以下步骤操作&#xff1a; 1、打开 IntelliJ IDEA 软件&#xff0c;进入代码编辑主界面。 点击编辑窗口上方的“File”菜单项。 2、在下拉子菜单中&#xff0c;选择“Settings”选项&#xff08;如果你使用的是 macOS&#xff0c;可…

2024.3.17 机器学习周报

引言 Abstract 文献阅读 1、题目 R-TRANSFORMER: RECURRENT NEURAL NETWORK ENHANCED TRANSFORMER 2、引言 递归神经网络长期以来一直是序列建模的主要选择。然而&#xff0c;它严重遭受两个问题&#xff1a;在捕获非常长期的依赖性和无法并行化的顺序计算过程中无能为力…

Qt 实现 Asterix 报文解析库

【写在前面】 最近工作中需要解析 Cat 21 和 Cat 62 的 ADS-B 数据 ( 自己的工作包含航空领域 )。 然后&#xff0c;因为整个 Asterix 协议类别非常之多&#xff0c;每个类别的版本也多&#xff0c;纯手工实现每个版本解析根本不现实 ( 然鹅公司之前的解析库就是这么做的且做的…

01_什么是深度学习

人工智能包含了机器学习&#xff0c;而深度学习是机器学习的一个分支。 人工智能 试图将通常由人类完成的智力任务自动化—这就是人工智能。 用硬编码的方式实现人工智能&#xff0c;这称作符号主义人工智能Symbolic AI。其中包含专家系统。 机器学习 机器学习是一种替代符…

Linux操作系统-汇编LED驱动程序基础

一、汇编LED原理分析 IMX6ULL-LED灯硬件原理分析&#xff1a; 1、使能时钟&#xff0c;CCGR0-CCGR6这7个寄存器控制着IMX6ULL所有外设时钟的使能。为了简单&#xff0c;设置CCGR0-CCGR6这7个寄存器全部为0XFFFFFFFF&#xff0c;相当于使能全部外设时钟。&#xff08;在IMX6ULL芯…

【Stable Diffusion】入门-04:不同模型分类+代表作品+常用下载网站+使用技巧

目录 1 模型简介2 模型文件构成和加载位置2.1 存储位置2.2 加载模型 3 模型下载渠道3.1 HuggingFace3.2 Civitai 4 模型分类4.1 二次元模型4.2 写实模型4.3 2.5D模型 1 模型简介 拿图片给模型训练的这个过程&#xff0c;通常被叫做“喂图”。模型学习的内容不仅包括对具体事物…

Rust学习02:推荐一本入门书,免费的

都说Rust的学习曲线很陡峭&#xff0c;试过才知雀实不容易。 先说我的基础&#xff0c;非科班&#xff0c;自学Python&#xff0c;写过几个小程序。 我买书从来不扣扣嗖嗖的&#xff0c;所以先啃了几本Rust的入门书&#xff0c;包括&#xff1a; Tim McNamara的《Rust实战》&am…

Day40:安全开发-JavaEE应用SpringBoot框架JWT身份鉴权打包部署JARWAR

目录 SpringBoot-身份鉴权-JWT技术 SpringBoot-打包部署-JAR&WAR 思维导图 Java知识点 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方组件使用等. 框架库&#xff1a;MyBatis&…

idea将非UTF-8的properties修改为UTF-8编码的文件

需求背景 由于项目初始化时&#xff0c;properties文件的编码格式为ASCII编码格式&#xff0c;此时用idea打开该文件会默认展示UTF-8的编码内容&#xff0c;其中汉字可以正常展示&#xff0c;但是使用notepad打开却依旧时ASCII编码格式 idea配置 打开idea-setting-editor-f…

使用Lua编写Wireshark解析ProtoBuf插件

文章目录 Wireshark Protobuf Lua-dissectorStep 1: 获取 WiresharkStep 2: 配置ProtoBuf相关设置添加ProtoBuf查找路径 Step 3 运行和调试Lua代码1. 添加Lua脚本2. 运行和调试 Step 4: 写Lua Dissector代码 :)Step 5(Optional): Decode AsGithub工程地址 Wireshark Protobuf L…

YOLOv8训练好模型后,追加轮数继续训练、或者提前终止训练,缩减训练轮数

一、前言 而且此教程适用的情况是你已经训练好了此模型&#xff0c;想继续追加一些轮数。比如训练进度是120/120&#xff0c;已经完成了&#xff0c;继续追加10轮&#xff0c;或者你原先定的是200轮&#xff0c;希望缩减到150轮&#xff0c;可以使用我说的这个方法。为什么缩减…

【C语言】最大公约数

给定两个数&#xff0c;求这两个数的最大公约数 方法&#xff1a;辗转相除法 例&#xff1a;36与24的最小公约数 36/241...12 24/122...0 那么12就是36与24的最大公约数。 代码如下&#xff1a; #include <stdio.h> int main() { int a 0; int b 0; scan…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:RowSplit)

将子组件横向布局&#xff0c;并在每个子组件之间插入一根纵向的分割线。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 RowSplit通过分割线限制子组件的宽度。初始化…

FPGA和ASIC

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;这是我所总结作为学习的笔记第16篇,在本篇文章给大家介绍FPGA和ASIC。 一个四核i7的CPU的晶体管中有20亿的晶体管&#xff0c;需要链接起20亿的晶体管可不是一件容易的事情&#xff0c;所以设计一个CPU需要用年来算&#x…

挑战杯 机器视觉的试卷批改系统 - opencv python 视觉识别

文章目录 0 简介1 项目背景2 项目目的3 系统设计3.1 目标对象3.2 系统架构3.3 软件设计方案 4 图像预处理4.1 灰度二值化4.2 形态学处理4.3 算式提取4.4 倾斜校正4.5 字符分割 5 字符识别5.1 支持向量机原理5.2 基于SVM的字符识别5.3 SVM算法实现 6 算法测试7 系统实现8 最后 0…

第七课-----分支切平面

割平面方法的基本思想是对于一个优化问题而言&#xff0c;通过不断添加约束条件来切割可行域&#xff0c; 最终将可行域不断变小&#xff0c;相当于搜索空间变小。在LP中讲过&#xff0c;一个等式约束就等价于一个超平面&#xff0c;一个不等式约束就代表一个半空间&#xff0c…

17.搜索二维矩阵Ⅱ

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,2…

2.26回顾章节主体线索脉络,课程要求(评分)

3)翻译程序、汇编程序、编译程序、解释程序有什么差别&#xff1f;各自的特性是什么&#xff1f; 翻译程序是指把高级语言源程序翻译成机器语言程序&#xff08;目标代码&#xff09;的软件。 翻译程序有两种&#xff1a;一种是编译程序&#xff0c;它将高级语言源程序一次全部…

lua脚本的基础内容

官方地址&#xff1a;http://luajit.org/ 官方wiki地址&#xff1a;http://wiki.luajit.org/Home 推荐书籍&#xff1a; OpenResty 最佳实践&#xff1a;https://moonbingbing.gitbooks.io/openresty-best-practices/content/ lua基础文档&#xff1a;https://www.runoob.com/l…