【模拟】算法实战

news2024/10/6 20:26:52

文章目录

  • 一、算法原理
  • 二、算法实战
    • 1. leetcode1576 替换所有的问号
    • 2. leetcode495 提莫攻击
    • 3. leetcode6 N字形变换
    • 4. leetcode38 外观数列
    • 5. leetcode1419 数青蛙
  • 三、总结


一、算法原理

模拟就是用计算机来模拟题目中要求的操作,模拟题目通常具有代码量大、操作多、思路繁琐的特点。所谓的"模拟题",用一句老话所就是"照着葫芦画瓢",根据题目的表述进行筛选提取关键要素,按需求书写代码解决实际问题。


二、算法实战

1. leetcode1576 替换所有的问号

在这里插入图片描述
替换所有的问号

解题思路:

这是一道简单的模拟题,意思是一个字符串中有 '?' 字符,将些字符替换为'a' ~ 'z'中的任意一个字符后,使得这个字符串中不会出现连续两个以上的连续字符。首先我们遍历这个字符串,先找到字符 '?' 的位置,然后从'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++)
                {
                    if((i == 0 || ch != s[i-1]) && (i == s.size()-1 || ch != s[i+1])){
                        s[i] = ch;
                        break;
                    }                
                }
            }
        }
        return s;
    }
};

2. leetcode495 提莫攻击

在这里插入图片描述
提莫攻击

解题思路:

首先扫描这个数组,使用cnt统计答案,timeSeries[i]表示此时攻击的开始点,timeSeries[i+1]表示下一次攻击的开始点。

  • timeSeries[i + 1] - timeSeries[i] < duration,表示两次攻击重叠。cnt+=timeSeries[i + 1] - timeSeries[i]
  • timeSeries[i + 1] - timeSeries[i] >= duration,表示两次攻击不重叠, cnt+=duration。

因为最后一次攻击是肯定会持续完的,所以我们扫描数组的时候只需要扫描前n-1个元素。但是最后返回结果时候需要返回cnt+duration

代码实现:

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

3. leetcode6 N字形变换

在这里插入图片描述
N字形变换

解题思路:

首先我们应该先搞清楚从原字符串到目标字符串是如何变换而来的。

在这里插入图片描述

我们可以看到这个过程:先将该字符串以'N'字形的顺序依次填入一个二维数组中,然后将该二维数组中的内容从上到下一行一行拼接起来即可。这里我们可以从中找一些规律出来:

在这里插入图片描述

代码实现:

class Solution {
public:
    string convert(string s, int numRows) {
        string ret = "";
        if(numRows == 1)
            return s;
        int sub = 2*numRows - 2;
        for(int i = 0; i < numRows; i++)
        {
            // 处理第一行和最后一行
            if(i == 0 || i == numRows-1){
                for(int j = i; j < s.size(); j += sub){
                    ret += s[j];
                }
            }else{
                // 处理中间行
                for(int k = i, p = sub - k; k < s.size() || p < s.size(); k += sub, p += sub)
                {
                    if(k < s.size()) ret += s[k];
                    if(p < s.size()) ret += s[p];
                }
            }
        }
        return ret;
    }
};

4. leetcode38 外观数列

在这里插入图片描述
外观数列

解题思路:

题目告诉了我们数列的每一项的变换过程是通过上一项推导出来的,因此我们可以根据上一项模拟数列每一项的形成过程。在数列每一项的模拟过程中,我们依然使用滑动窗口的算法原理来实现。

代码实现:

class Solution {
public:
    string countAndSay(int n) {
        // 使用双指针算法进行模拟
        string start = "1";
        while(--n)
        {
            string tmp;
            for(int left = 0, right = 0; left < start.size(); right++)
            {
                if(start[left] != start[right])
                {
                    tmp += to_string(right - left);
                    tmp += start[left];
                    left = right;
                }
            }
            start = tmp;
        }
        return start;
    }
};

5. leetcode1419 数青蛙

在这里插入图片描述
数青蛙

解题思路:

这道题目属于典型的比较难的模拟题,先开一个哈希表,然后将"croak"按照<char, int>的方式映射进哈希表,这里的int指的是"croak"中字符的下标。开一个cnt来计数,统计每一个字符出现的次数。

从前向后遍历字符串,如果ch=='c',说明需要一只青蛙开始发出蛙鸣,如果前面统计cnt[n - 1],这里的n-1表示"croak"字符串的最后一个’k’的下标,意思是如果cnt[n - 1]已经出现过了,说明前面有一只青蛙已经将"croak",这个字符串全部叫了一遍,那么我们让前面的青蛙继续从头开始叫就可以了,不需要增加青蛙的数量,因此让cnt[n - 1]--,cnt[0]++,如果cnt[n - 1] == 0, 则直接让cnt[0]++。

如果ch!='c',则说明一只青蛙正在发出蛙鸣的过程中,此时我们让此时青蛙发出蛙鸣的字符的前一个字符的下标cnt[c前面的字符]- -,然后让正在遍历的字符数量cnt[c]++,如果中途发现cnt[c前面的字符] == 0, 说明该字符连续出现了两次以上,或者字幕出现的顺序有问题。直接返回-1即可。

最后我们统计的时候只需要关心"croak"中最后一个’k’出现了几次即可,同时,我们还需要遍历cnt中除最后一个元素外,看前面的字母出现的次数是否为0,若不为0,说明字幕出现的顺序不符合要求,直接返回-1。

代码实现:

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        string t = "croak";
        int n = t.size();
        vector<int> cnt(n);

        unordered_map<char, int> hash;
        for(int i = 0; i < n; i++) hash[t[i]] = i;

        for(char ch : croakOfFrogs)
        {
            if(ch == 'c'){
                if(cnt[n - 1]) cnt[n - 1]--;
                cnt[0]++;
            }else{
                int i = hash[ch];
                if(cnt[i - 1])
                    cnt[i - 1]--, cnt[i]++;
                else return -1;
            }
        }
        for(int i = 0; i < n - 1; i++)
            if(cnt[i] != 0) return -1;
        return cnt[n - 1];
    }
};

三、总结

模拟的过程就是对真实场景尽可能的模拟,但我们需要注意的是:模拟题并没有我们所想象的那么简单,它的代码中可能会有很多的'坑',我们在写模拟算法的过程中需要谨慎。

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

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

相关文章

网络编程套接字(4):日志和守护进程

文章目录 网络编程套接字(4): 日志和守护进程5. 增加日志功能6. 守护进程6.1 进程知识补充(1) 进程组(2) 任务(3) 会话 6.2 守护进程(1) 概念(2) 创建守护进程 网络编程套接字(4): 日志和守护进程 5. 增加日志功能 接着上篇的内容&#xff0c;增加日志功能可以更好地&#xf…

16.WebSocket聊天室

基于SpringBoot 2.6.11 1.WebSocket WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议&#xff0c;可以在html页面直接使用。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在 WebSocket A…

2021年12月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;书架 John最近买了一个书架用来存放奶牛养殖书籍&#xff0c;但书架很快被存满了&#xff0c;只剩最顶层有空余。 John共有N头奶牛(1 ≤ N ≤ 20,000)&#xff0c;每头奶牛有自己的高度Hi(1 ≤ Hi ≤ 10,000)&#xff0c;N头奶牛的总高度为S。书架高度为B(1 ≤…

亚马逊云科技 云技能孵化营——我的云技能之旅

文章目录 每日一句正能量前言活动流程后记 每日一句正能量 不能在已经获得足够多的成功时&#xff0c;还对自己的能力保持怀疑&#xff0c;露出自信的微笑&#xff0c;走出自信的步伐&#xff0c;做一个自信的人&#xff01; 前言 亚马逊云科技 (Amazon Web Services) 是全球云…

Kao框架学习

中间件&#xff1a;洋葱模型 这是官网上给出的示例&#xff0c;从logger依次往下执行&#xff0c;执行到最底层的response往回退&#xff0c;结构很像同心圆的洋葱从外层向内层再由内层向外层。 next表示暂停当前层的代码进入下一层&#xff0c; 当最后一层执行完毕开始回溯&a…

学习完毕JavaSE的感想

今天&#xff0c;把Java复习完毕了&#xff0c;之前学习的时候&#xff0c;学校里学的总是有限的 &#xff0c;自己上手操作之后才发觉差的很多&#xff0c;部署服务器发现要学操作系统&#xff0c;学完了web基础 &#xff0c;又发现还得学前后端分离vue react这些&#xff0c;…

基于ensp的中大型企业网络安全解决方案的设计与实施

一、需求背景 公司部门具体背景&#xff1a;公司共设有人事部、财务部、销售部、市场部四个部门以及一个员工宿舍楼&#xff0c;公司有对外互联网业务需要提供。公司内存在重要部门需要保护数据安全以及访问控制。 &#xff08;1&#xff09;根据客户需求、部门、拓扑&#xf…

代码搜索技巧

在IDE中搜索代码时&#xff0c;经常会被相近的无关代码干扰&#xff0c;如筛选所有使用协程的代码段&#xff0c; 可见有大量“噪音”。 可使用IDE提供的正则表达式功能 如 使用 \bgo ,即匹配go开头的&#xff0c;且之后为空格的所有选项 使用 \bgo func,即匹配到了所有使用协程…

C++学习vector

1,把list的相关函数都实现出来&#xff08;未完&#xff09; 2&#xff0c; 运行结果&#xff1a;

等保测评各个级别的详细内容

等保测评是指信息系统安全等级保护测评&#xff0c;是我国信息安全领域中的一项重要工作。根据国家标准《信息系统安全等级保护基本要求》(GB/T 22239-2008)和《信息系统安全等级保护测评技术要求》(GB/T 25070-2010)。 等保测评分为五个级别&#xff0c;分别是&#xff1a;一级…

达梦数据库管理用户和创建用户介绍

概述 本文主要对达梦数据库管理用户和创建用户进行介绍和总结。 1.管理用户介绍 1.1 达梦安全机制 任何数据库设计和使用都需要考虑安全机制&#xff0c;达梦数据库采用“三权分立”或“四权分立”的安全机制&#xff0c;将系统中所有的权限按照类型进行划分&#xff0c;为每…

JZ12 矩阵中的路径

剑指Offer编程链接&#xff1a;JZ12 题目描述&#xff1a; 思路&#xff1a;递归回溯的方法&#xff0c;总结一下什么情况需要使用递归&#xff1a; 递归在解决问题时&#xff0c;通常涉及以下情况&#xff1a; 问题可被分解为较小的相似子问题。子问题与原问题具有相同的结…

eclipse设置字体大小

打开IDE&#xff0c;选择window->perferences 选择颜色与字体&#xff0c;选择basic 选中text-font之后选择编辑 选择合适的大小之后选择应用并关闭即可 结果

权限提升-Windows本地提权-AT+SC+PS命令-进程迁移-令牌窃取-getsystem+UAC

权限提升基础信息 1、具体有哪些权限需要我们了解掌握的&#xff1f; 后台权限&#xff0c;网站权限&#xff0c;数据库权限&#xff0c;接口权限&#xff0c;系统权限&#xff0c;域控权限等 2、以上常见权限获取方法简要归类说明&#xff1f; 后台权限&#xff1a;SQL注入,数…

ELK日志收集系统

一、概述 1、ELK由三个组件构成 2、作用 日志收集 日志分析 日志可视化 3、为什么使用&#xff1f; 日志对于分析系统、应用的状态十分重要&#xff0c;但一般日志的量会比较大&#xff0c;并且比较分散。 如果管理的服务器或者程序比较少的情况我们还可以逐一…

数据结构学习 --4 串

数据结构学习 --1 绪论 数据结构学习 --2 线性表 数据结构学习 --3 栈&#xff0c;队列和数组 数据结构学习 --4 串 数据结构学习 --5 树和二叉树 数据结构学习 --6 图 数据结构学习 --7 查找 数据结构学习 --8 排序 本人学习记录使用 希望对大家帮助 不当之处希望大家帮忙纠正…

二极管:常用二极管封装

常用二极管封装 1、DO-41 2、DO-201AD 3、DO-35 4、LL-34 5、DO-214AC (SMA) 6、SMB

电脑数据丢失如何恢复?最常见的2种数据恢复方法!

大家使用电脑的时候是否有发生过不小心删除数据&#xff0c;或者数据不明丢失的情况呢&#xff1f;相信九成都是有的&#xff0c;那么当你的数据不小心删除或是丢失的话&#xff0c;有没有电脑数据恢复方法&#xff1f;其实很多人当自己电脑的数据丢失后&#xff0c;如果不是很…

一直傻傻分不清 count(*) count(id) count(1) 这次终于整明白了

COUNT(*)、COUNT(id) 和 COUNT(1) 是用于计算行数的 SQL 聚合函数&#xff0c;它们在某些方面有一些区别。 - COUNT(*)&#xff1a;COUNT(*) 是一种特殊的语法&#xff0c;它返回结果集中的行数&#xff0c;不考虑任何列的值。它会将表中的每一行都计数&#xff0c;包括含有NU…