专题六_模拟_算法详细总结

news2024/9/20 5:47:29

目录

模拟算法

1.模拟算法流程(一定要在草稿纸上演算一遍流程)

2.把流程转换成代码

1. 替换所有的问号(easy)

解析:

1.暴力:

2.优化:(找规律)

总结:

2. 提莫攻击(easy)

解析:

1.暴力:

2.优化:

3. N 字形变换(medium)

解析:

1)暴力:

2)优化:

总结:

4. 外观数列 (medium)

解析:

1)暴力:

2)优化(小demo):

总结:

5. 数⻘蛙(medium)

解析:

1)暴力:

2)优化:

总结:


模拟算法

特点就是思路比较简单,特别考验的是如何把里路转换成代码的能力。

1.模拟算法流程(一定要在草稿纸上演算一遍流程)

2.把流程转换成代码

相对来说,模拟题读题就知道是跟着题目的意思一步一步走,但是但凡觉得只是暴力求解时间复杂度和空间复杂度太高了,那么就要转换思想去找规律。模拟题的优化,就是不断的找规律。

1. 替换所有的问号(easy)

就是遍历整个字符串,然后替换里面的所有 '?' ,但是不能存在重复的字符。

解析:

1.暴力:

我开始第一次做的时候,就是创建了心得字符串str,然后每次再遇到不是'?' 的时候就加入,是就改变这个字符,但是在这之前为了保证字符不连续重复,我就用a和b来分别定义字符串中没有出现过的字符,然后用下标奇偶的关系就可以保证a,b交错不连续重复。

class Solution {
public:
    string modifyString(string _s) {
        string s;
        unordered_map<char,int> hash;
        for(auto e : _s) if(e!='?') hash[e]++;
        char a='a',b='a';
        while(hash[a]) a++; hash[a]++;
        while(hash[b]) b++;
        int i=1;
        for(auto e : _s)
        {
            if(e!='?') s+=e;
            else
            {
                if(i%2==0) s+=a;
                else s+=b;
            }
            i++;
        }
        return s;
    }
};

2.优化:(找规律)

线性时间复杂度,而且空间复杂度为O(1),只在原来的字符串s上进行修改,那么时间复杂度很低O(N),只需要早原串的基础上进行修改就行。

class Solution {
public:
    string modifyString(string s) {
        int n=s.size();
        for(int i=0;i<n;i++)
        {
            if(s[i]=='?')
            {
                for(char ch='a';ch<='z';ch++)
                {
                    if((i==0||ch!=s[i-1])&&(i==n-1||ch!=s[i+1]))
                    {
                        s[i]=ch;
                        break;
                    }
                }
            }
        }
        return s;
    }
};

总结:

像这种模拟题,就要尽可能的想到简便的办法来进行优化,其实很简单。

2. 提莫攻击(easy)

这题题意很简单,就是再中毒时间内,如果继续被攻击,那么就刷新中毒时间,从头开始,那么只需要计算数组每两个数之间的间隙大小是否大于中毒时间即可。

解析:

1.暴力:

想暴力,就是求出每个时间间隔然后再与中毒时间进行比较,小于中毒时间的就只加上这个间隙,否者就加上完整的中毒时间。

2.优化:

根据题目意思就是要看判断再你的下一次攻击时,对方是否再中毒期间,如果是,那么就要进行重置,就只要加上从上一次中毒到这次中毒的间隙,若这个间隙大于或等于中毒时间,那么就只能加上这个中毒时间即可,最后遍历完整个数组后就再加上最后一次的中毒时长就是最后的结果,其实跟暴力没啥区别。

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

3. N 字形变换(medium)

题意就是将字符串按照给出的行数,形成N行大小的Z字形,然后一行一行的读出字符,再进行输出。

解析:

1)暴力:

暴力肯定最开始想到就是按照字符串的下标顺序来进行存入二维数组里面,比如:这个字符串按照下标开始存入二维数组的第一列然后再开始斜边存入,再存入第二列,再次斜边存入等接下来存完整个二维数组,时间复杂度和空间复杂度都达到O(N^2),但是这题数据量小,可以试试,还是能过的,但是这种办法,我想这就头疼。必须要优化一下

2)优化:

那么说是优化,其实就是找规律,模拟,现根据题目意思进行模拟运算,比如创建一个二维数组来分别进行填入字符串的每一位,但是这一不管是时间复杂度还是空间复杂度都是O(N^2)都太过于复杂
那么就要对他进行优化,对于模拟题,优化都是采用找规律的形式,
1)首先看第一行,每两个数字之间都是由一个公差来决定的,那么就要想办法求出公差,公差就是两倍的行数减去2,或者,就是(二维矩阵行数-1)*2得到公差
2)那么最后一行同样是由一个公差来得到。
3)那么其间的k行[1,n-1]行就都是由两个数,来分别+公差d来组成的,第一个数就是k行的首元素,第二个数就是 d-k 为下标的元素

class Solution {
public:
    string convert(string s, int numRows) {
        int n=s.size();
        if(numRows==1) return s;
        string ret;
        //第一行
        //求公差
        int d=numRows*2-2;
        int prelude=0;
        while(prelude<n) ret+=s[prelude],prelude+=d;

        //中间行
        for(int k=1;k<=numRows-2;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];
            }
        }

        //最后一行
        int k=numRows-1;
        while(k<n) ret+=s[k],k+=d;

        return ret;
    }
};

总结:

对于这种题目有点复杂的模拟,就一定要耐心找到规律,就会变得很简单,重点就是如何把规律变成代码的形式。

4. 外观数列 (medium)

这题相对来说真的比较简单了,只要理解题目意思,真的模拟起来so easy~
题目就是说按照读法生成下一个字符串 "1" -> "1个1" -> "11"
那么"11" -> "2个1" -> "21"等

解析:

1)暴力:

暴力下就是不停的求出每一个次数条件下的字符串,其实优化也大差不差,都是再while里进行。

2)优化(小demo):

就是要再while外面记录s,每次循环一次们都要记录s,最后返回s。再就是在while里面,要记住每次循环完都要swap(ret,str) ,这样能保证ret每次都是要更新的新字符串,str每次都是上一次的字符串。

模拟这个字符串生成的规律,设置三个字符串,每次都更新str,用双指针left和right来记录重复的字符,并更新到ret里面,然后每次当right走到结尾时候,就把ret赋值给s,并且交换ret跟str,来达到再次更新的目的,最后返回s即可。

class Solution {
public:
    string countAndSay(int _n) {
        string ret;
        string str=to_string(1);
        if(_n==1) return str;
        string s;
        while(--_n)
        {
            int n=str.size();
            for(int left=0,right=0;right<n;right++)
            {
                if(str[left]!=str[right])
                {
                    ret+=to_string(right-left);
                    ret+=str[left];
                    left=right;
                }
                if(right==n-1)
                {
                    ret+=to_string(right-left+1);
                    ret+=str[left];
                }
            }
            s=ret;
            swap(str,ret);
            ret.clear();
        }
        return s;
    }
};

总结:

有些比较简单的模拟,真的一眼就能只知道怎么写,可能这就是提升吧。

5. 数⻘蛙(medium)

题目意思就是用最少的青蛙喊出最长的字符串,并且要满足"croak" 并且顺序要正确才行。

解析:

1)暴力:

这题如果想不上优化,那还真有点暴力,5个else if() 来判断条件,判断前面是否有字符存在满足条件是我当前字符的前一个,如果是就继续,不是就直接返回-1

2)优化:

首先就是解决5个else if()的问题,可以用一个unordered_map<char,int> index;来将字符串装起来,将字符串的字符与下标进行映射,然后创建一个hash表,这个hash表专门装入五个字符“蛙叫”

hash表,来记录最少青蛙的只数。

eg:

我现在读到的字符是ch=‘o’,那么我就要判断前面的字符‘r’是否存在过,如果现在存在,就证明这一只青蛙可以喊道我这个‘o’,否则就说明是错误的,返回-1

又比如:我已经有青蛙喊完了一遍,又碰到一个字符是ch,此时我的hash['k']==1,就说明有一次青蛙已经喊完了,但是,有碰到ch=='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')
            {
                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]++;
            }
        }

        for(int i=0;i<n-1;i++) if(hash[i]!=0) return -1;
        return hash[n-1];
    }
};

总结:

主要优化就是要找到其中的规律,可以很暴力的求解,但是这样往往都十分消耗精力,可以多想一步,说不定就解决了多次else if()的问题。这个算法里面,用index将字符跟下标进行对应,很完美的解决了else if()来判断每次读到哪个字符,这个位置是否要加减的问题。

总结一下吧~模拟题相对来说确实比较轻松,只要读懂题意跟着题目一步步走一般问题不大,还是那句话,熟能生巧,本章节对我有很大促进作用,希望对你有用!!

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

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

相关文章

MySQL数据库迁移与备份实录

这里写目录标题 事情起因的概述查看磁盘空间使用情况为了进一步的明确宕机原因&#xff0c;查看MySQL日志信息进一步排查 如何针对磁盘空间不足进行挂载区域的修改以及数据的迁移与备份分析与梳理如何修改MySQL数据卷的挂载位置停止MySQL服务备份 MySQL 配置文件迁移 MySQL 数据…

MTK zephyr平台:USB升级、枚举流程

一、USB升级流程 通过代码及log分析,当前平台升级过程在PL阶段进行 USB download相关代码 mtk/modules/hal/boot/preloader/platform/flashc/ mtk/modules/hal/boot/preloader/platform/board_name/flash/ mtk/modules/hal/boot/preloader/platform/board_name/src/drive…

【Python报错已解决】ModuleNotFoundError: No module named ‘paddle‘

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

开放标准如何破解企业数字化与可持续发展的困境:The Open Group引领生态系统架构创新

应对数字化与可持续发展的双重挑战&#xff0c;开放标准是关键 在当今快速变化的商业环境中&#xff0c;企业不仅需要通过数字化转型提升竞争力&#xff0c;还面临日益严格的可持续发展要求。开放标准正在成为企业破解这一双重挑战的核心工具。The Open Group 2024生态系统架构…

智能BI项目第四期

开发图表管理功能 规划思路 首先需要做一个列表页。后端已经在星球提供了一个基础的万能项目模板&#xff0c;包含增删改查接口&#xff0c;我们只需要在此基础上进行定制化开发即可。所以本期后端的开发量不多&#xff0c;只需要复用即可&#xff0c;主要是前端。 规划功能…

【IPV6从入门到起飞】5-4 IPV6+Home Assistant(ESP32+MQTT+ILI9488)远程留言墙

IPV6Home Assistant[ESP32MQTTILI9488]远程留言墙 1 背景2 Home Assistant 配置2-1 配置 yaml2-2 效果 3 ESP32 配置3-1 使用 TFF_eSPI 库3-2 修改默认的SPI屏幕配置文件3-3 接线3-4 ESP32 工程代码 4 测试4-1 留言板设置内容4-2 ESP32 屏幕显示 5 后记 1 背景 在前面我们的几…

自动驾驶中的决策规划技术分享--轻舟智航

文章目录 0.概述&#xff1a;1 导航模块2 决策模块2.1 车道决策2.2 障碍物决策 3 轨迹规划3.1 时空分离规划3.2 时空联合规划 4 对比 0.概述&#xff1a; 李仁杰&#xff0c;轻舟智航规划算法负责人&#xff0c;自动驾驶决策与规划技术专家。 在自动驾驶系统中&#xff0c;决策…

Win10 录屏秘籍大公开:从新手到高手的进阶之路

之前因为某些原因不方便到客户那里进行软件培训&#xff0c;我们就发现录屏讲解供客户随时查看的方式好像更有效果。这次我就介绍一些能够实现win10怎么录屏操作的工具讲解。 1.福昕录屏大师 链接&#xff1a;www.foxitsoftware.cn/REC/ 这个工具是一款专业的电脑录屏软件&a…

SVN泄露 CTFHUB 解题笔记

参考大佬链接CTFHub | SVN泄露_ctfhubsvn泄露-CSDN博客 先下载插件 然后把GIT&#xff1b;里面的代码 乱盘上去 python2 不知道需不需要 先装了 再说。。。我的是裸机~ 开始作妖模式 Ubuntu 22.10 | Installati.one 上面一行的代码 链接 下面 插件 GITHUB页面下面的代码 d…

企业网络安全关键:防御措施和应急响应

感谢浪浪云支持发布 浪浪云活动链接 &#xff1a;https://langlangy.cn/?i8afa52 文章目录 什么是网络安全常见的网络安全威胁病毒和恶意软件网络钓鱼拒绝服务攻击中间人攻击社会工程学 基本的网络安全措施强密码策略双因素认证安装和更新防病毒软件定期备份 高级的网络安全方…

Java-面向对象编程(基础部分)

类和对象的区别和联系 类&#xff1a;类是封装对象的属性和行为的载体&#xff0c;在Java语言中对象的属性以成员变量的形式存在&#xff0c;而对象的方法以成员方法的形式存在。 对象&#xff1a;Java是面向对象的程序设计语言&#xff0c;对象是由类抽象出来的&#xff0c;…

使用 MobaXterm 远程连接 Linux 虚拟机并实现文件传输

文章目录 前言一、什么是 MobaXterm二 、MobaXterm 安装三、使用 MobaXterm 远程连接 Linux 虚拟机1. 准备工作2. 创建 SSH 连接3. 登录虚拟机 四、使用 MobaXterm 进行文件传输总结 前言 在日常开发和运维中&#xff0c;Windows 用户经常需要通过远程连接到 Linux 服务器进行…

链式栈讲解

文章目录 &#x1f34a;自我介绍&#x1f34a;链式栈入栈和出栈linkstack.hlinkstack.c 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &#x1f34a;自我介绍 Hello,大家好&#xff0c;我是小珑也要…

UBUNTU20.04安装CH384串口卡驱动

继续上文&#xff1a;统信UOS安装CH384串口卡驱动-CSDN博客 统信UOS系统成功安装CH384串口驱动后&#xff0c;继续在ubuntu20.04下安装驱动&#xff0c;发现一直报错&#xff0c;原因是内核驱动不一致。 解决办法&#xff1a; 1. 下载最新的驱动。CH35XCH384驱动源文件资源-C…

【WPF】02 按钮控件圆角配置及状态切换

按钮圆角 先从工具箱里拖进来一个Button控件&#xff0c;然后对这个按钮进行美化。 首先在 xaml 里按钮控件部分 添加如下代码&#xff1a; <Button x:Name"btnLogin" Content"登录" HorizontalAlignment"Center" Margin"0,399,0,0&q…

报错合计-1

向开发描述&#xff1a;先勾选一个病灶后复制&#xff0c;控制台报错 报错类型查询后为前端DOM节点相关报错&#xff0c;提给前端开发 报错解释&#xff1a; TypeError: Failed to execute selectNode on Range: parameter 1 is not of type Node 这个错误表明你尝试使用 Range…

【机器学习】:深潜智能的底层逻辑、前沿探索与未来展望】

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 在科技的浩瀚星空中&#xff0c;机器学习犹如一颗璀璨的新星&#xff0c;以其独特的魅力和无限潜力&#xff0c;引领着我们向智能的深处探索。今天&#xff0c;我们将一同踏上这场深度之旅&#xff0c;不仅解析…

AI时代,服务器厂商能否打破薄利的命运?

文&#xff5c;刘俊宏 编&#xff5c;王一粟 AI大模型正在引发新一轮的“算力焦渴”。 近日&#xff0c;OpenAI刚发布的o1大模型再次刷新了大模型能力的上限。对比上一次迭代的版本&#xff0c;o1的推理能力全方位“吊打”了GPT-4o。更优秀的能力&#xff0c;来自与o1将思维…

Flink官方文档

Flink官方文档&#xff08;全面、详细&#xff09;&#xff1a;https://nightlies.apache.org/flink/flink-docs-master/zh/

【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL24

边沿检测 有一个缓慢变化的1bit信号a&#xff0c;编写一个程序检测a信号的上升沿给出指示信号rise&#xff0c;当a信号出现下降沿时给出指示信号down。 注&#xff1a;rise,down应为单脉冲信号&#xff0c;在相应边沿出现时的下一个时钟为高&#xff0c;之后恢复到0&#xff0…