算法——模拟专题(一篇搞定)

news2024/9/21 10:58:06

在本专栏已经更新双指针算法,滑动窗口算法,二分查找算法,前缀和算法以及位运算算法,欢迎大家跳转至相关专题阅读

此篇文章为大家带来算法专栏的模拟专题

模拟算法本质就是比葫芦画瓢,思路比较简单,就是将演算流程转化为代码

目录

1.替换所有的问号

1.1解析

1.2题解

2.提莫攻击

2.1解析

2.2题解

3.N字形变化

3.1解析

3.2题解

4.外观数组

4.1题解

4.2题解

5.数青蛙

5.1解析

优化

5.2题解

谢谢您的访问!!期待您的关注!!



1.替换所有的问号

题目:. - 力扣(LeetCode)

1.1解析

本质上就是将字符串里面的所有 ? 字符 替换成任何一个a ~ z的字符,但是要,满足替换后的字符与该字符前一个字符和后一个字符不能相等

那么我们直接简单遍历后判断即可

但是要注意边界条件,第一个字符只能判断后一个字符,第二个字符只能判断前一个字符

1.2题解
class Solution {
     public String modifyString(String s) {
         char[] str = s.toCharArray();
         int n = str.length;
         for(int i = 0; i < n; i++){
             if(str[i] == '?'){
                 for(char ch = 'a'; ch <= 'z'; ch++){
                     if((i == 0 || ch != str[i-1]) && (i == n-1 || ch != str[i+1])){
                         str[i] = ch;
                         break;
                     }
                 }
             }
         }
         return String.valueOf(str);
     }
 }

2.提莫攻击

题目:. - 力扣(LeetCode)

2.1解析

题目给定一个数组,数组里面的元素代表英雄在第几秒接受攻击.那么英雄在接受攻击的时候如果是处于正常状态,那么就正常晕眩,此时总晕眩时间就加上duration即可; 但是如果再接受攻击的时候,上一个攻击的晕眩还没结束,那么就要重置晕眩,那么这段时间的晕眩时间就是 两个数组元素的时间差

因此,我们只需遍历数组,判断数组前一个元素和后一个元素只差是不是 >= duration,如果大于,那么 sum+= duration.小于的话就 sum += timeSeries[i+1] - timeSeries[i];

但是要注意:数组最后一个元素是没有后一个元素的,因此我们遍历完数组最后得到的结果要 + duration

2.2题解
 class Solution {
     public int findPoisonedDuration(int[] timeSeries, int duration) {
         int sum = 0;
         for(int i = 0; i < timeSeries.length-1; i++){
             sum += Math.min(timeSeries[i+1]-timeSeries[i],duration);
         }
         return sum + duration;
     }
 }

3.N字形变化

题目:. - 力扣(LeetCode)

3.1解析

遇到这种稍微复杂的题,我们可以试着找一下规律

如图所示,我们将字符串形成的下N字型时,各个位置下标都表明好来寻找规律

我们会发现,第一和最后一行,每两个元素之间的下标差是都是6;至于中间的行,我们可以成对看,即[1 5] [7 11],这样会发现,1 与 7 之间 和 5 与11 之间的差数也都是6;同理,[2 4] [8 10]也是一样的规律

因此我们只需要找出6这个数字的规律即可,题目的变量是n = 4,那么6 = 2 n - 2,是不是真的如此呢??

我们让n = 3,再次模拟,看看 差数 是不是 = 4即可

如图所示,那么我们两个下标之间的差数就是 2 n - 2

我们也不难发现,第一行的下标是从0开始的,以2n-2为公差的等差数列

第2行则两组等差数列,一组是从1开始,以2n-2为公差的等差数列,第二组就是从n - 1开始,以2

n-2为开始的等差数列

因此我们可以总结出下面这张图:

因此,我们横向遍历的时候,根据下标拿到对应的字符,再拼接即可

注意:如果n = 1的话,那么d就会 = 0,就会造成死循环,因此我们要处理边界情况

3.2题解
 
public static String convert(String s, int numRows) {
         if(numRows == 1){
             return s;
         }
         StringBuffer ret = new StringBuffer();
         int d = 2 * numRows - 2;
         char[] str = s.toCharArray();
         int n = str.length;
         //处理第一行
         for(int i = 0; i < n; i += d){
             ret.append(str[i]);
         }
 ​
         //处理中间行
         for(int i = 1; i < numRows-1; i++){
             for(int k = i,j = d-i; k < n || j < n; k += d,j += d){
                 if(k < n){
                     ret.append(str[k]);
                 }
                 if(j < n){
                     ret.append(str[j]);
                 }
             }
         }
 ​
         //处理最后一行
         for(int i = numRows-1; i < n; i += d){
             ret.append(str[i]);
         }
 ​
         return ret.toString();
     }

4.外观数组

题目:. - 力扣(LeetCode)

4.1题解

题目实际上就是要我们对一个字符串进行描述,如果这个字符串为 "1211",那么就是1个1,1个2,2个1,那么对他描述救是111221,对"111221"描述就是 "312211"

因此我们只需要遍历当前字符串,判断有几个相同连在一起的相同字符,用count记录,再拼接上字符串即可

对于记录的过程,我们可以利用双指针

fast一直往前走,直到遇到某个数不等于slow位置的值,那么count = fast - slow;接着slow = fast,再继续记录

4.2题解
class Solution {
     public String countAndSay(int num) {
         String ret = "1";
         for(int i = 1; i < num; i++){//只需要循环n-1次
             StringBuffer tmp = new StringBuffer();
             int slow = 0, fast = 0, n = ret.length();
             while(fast < n){
                 while(fast < n && ret.charAt(fast) == ret.charAt(slow)){
                     fast++;
                 }
                 tmp.append(Integer.toString(fast-slow));
                 tmp.append(ret.charAt(slow));
                 slow = fast;
             }
             ret = tmp.toString();
         }
         return ret;
     }
 }

5.数青蛙

题目:. - 力扣(LeetCode)

5.1解析

题目实际上就是给一个字符串,这个字符串是由若干个零散的"croak"组成的,而一个croak就是一个叫声,我们要判断要形成所给字符串,最少要几只青蛙

那么就会出现3种情况:

(1)类似"croakcroak"

是由若干个完整的croak组成的,那么一个青蛙叫完"croak"后,还可以继续叫第二个"croak",因此最少要1只青蛙

(2)类似"crcoakroak"

那么在第一只青蛙叫到"cr"后,又出现了c,因此是由2个零散的croak组成的,最少要2只

(3)类似"croakcrook"

会出现不是"croak"的组合,那么就不能被青蛙叫出来,直接返回-1

我们的核心就在于一只青蛙能否叫出一个完整的"croak"

我们可以利用哈希表来存当前这个"croak"的情况

如图所示,当我们判断的字符是c的时候,对应哈希表中的c的个数就要++,继续遍历

当我们继续遍历到'r'的时候,就要回头判断记录'c'字符是否大于0,即c字符是否被叫过,如果没有(为0),那么直接返回-1;如果有,那么说明此时青蛙叫到了'r'字符,那么'r'字符在哈希表中的数量就+1,而先前的'c'就-1;依次类推,当判断到'o'的时候就要回头看r是否被叫过.....,这样,但最后k = 1的时候,说明一个完整的"croak"被叫完了.

但是如上述例子,但我们遍历到第二个c的时候,实际上是可以由第一只青蛙继续叫的,因此我们在遍历到c字符的时候,就要判断此时哈希表中的'k'的数量是否>0.如果>0则要让这个'k'的数量-1,而'c'的数量+1,模拟重复叫的过程

当我们遍历完字符串后,哈续表中k的数量就是最少青蛙的个数,而此时其余的"croa"字符数量一定都是0,如果不是,说明有多余字符,那么返回-1

优化

如果我们直接按照上面的思路,在遇到'c'的时候判断'k',遇到'r'的时候判断'c'....,那么我们需要写5个if-else,

这道题是把"croak"当成一个已知条件,但是如果"croak"未知,或者这个字符串长度不止5,而是更长,那么我们就不能写那么多if-else

如果我们能把"croak"每个对应的位置关系记录下来就好了,像数组那样

我们可以利用哈希表来记录下"croak"每个字符对应的位置关系.

那么我们在遍历到每个字符的时候,就可以直接从哈希表中拿到这个字符的前一个字符进行判断了

5.2题解
 class Solution {
     public static int minNumberOfFrogs(String croakOfFrogs) {
         String t = "croak";
         int len = t.length();
         char[] str = croakOfFrogs.toCharArray();
         int[] hash = new int[len];
         Map<Character,Integer> index = new HashMap<>();
         for(int i = 0; i < len; i++){
             index.put(t.charAt(i),i);
         }
         for(char ch : str){
             if(ch == t.charAt(0)){
                 if(hash[len-1] != 0){
                     hash[len-1]--;
                 }
                 hash[0]++;
             }else{
                 int i = index.get(ch);
                 if(hash[i-1] == 0){
                     return -1;
                 }
                 hash[i-1]--;
                 hash[i]++;
             }
         }
         for(int i = 0; i < len-1; i++){
             if(hash[i] != 0){
                 return -1;
             }
         }
         return hash[len-1];
     }
 }


谢谢您的访问!!期待您的关注!!

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

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

相关文章

eclipse导入svn项目

1、配置maven 2、用svn引入项目 3一直点击next,到最后选完成。

Orangedx:引领新一轮 BTCFi 浪潮

“OrangeDx 作为新一轮 BTCFi 浪潮引领者被市场寄予厚望 &#xff0c;前不久在 FinceptorApp 的平台的公开销售 20 万美元的额度仅在几秒售罄&#xff0c;而其即将以 Startup 方式登陆 Gate 平台也同样备受市场期待。” 自 Ordinals 面向市场为比特币生态带来全新的资产发行方案…

函数作用域和块级作用域:JavaScript中的变量作用域解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

OpenGL学习笔记【4】——创建窗口,给窗口添加渲染颜色

一、前三章节的前情回顾 章节一&#xff1a;上下文(Context) OpenGL学习笔记【1】——简介-CSDN博客 章节一讲述了OpenGL在渲染的时候需要一个Context来记录了OpenGL渲染需要的所有信息和状态&#xff0c;可以把上下文理解成一个大的结构体&#xff0c;它里面记录了当前绘制使…

【@changesets/cli】变更集实战教程

一、背景概述 前端目前基于Monorepo架构的npm包开发很普遍&#xff0c;在开发完毕后&#xff0c;我们需要对包进行版本号升级&#xff0c;并且部署&#xff0c;这些操作如果是手动来操作的话&#xff0c;很麻烦&#xff0c;而且容易出错。 例如有这样的场景&#xff1a; -ap…

【可用Claude Opus模型】Claude3国内镜像站,亲测完全超越GPT-4(可用Claude Opus,官网价值20刀)

#今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用Claude 3吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像站到处都是…

C++ 扫描当前路径下文件并删除大文件

C 扫描当前路径下文件并删除大文件 C获取当前路径扫描文件路径下规定后缀名称的文件计算文件大小 1. 获取当前路径 使用<Windows.h>中的GetCurrentDirectory方法实现&#xff0c;单独编写验证程序如下&#xff1a; #include<iostream> #include<Windows.h&g…

YOLOv9改进策略:IoU优化 | Powerful-IoU更好、更快的收敛IoU,效果秒杀CIoU、GIoU等 | 2024年最新IoU

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文独家改进&#xff1a;Powerful-IoU更好、更快的收敛IoU&#xff0c;是一种结合了目标尺寸自适应惩罚因子和基于锚框质量的梯度调节函数的损失函数 &#x1f4a1;&#x1f4a1;&#x1f4a1;MS COCO和PASCAL VOC数据集实现涨点 YO…

R语言基础入门

1.保存或加载工作空间 改变工作目录——进行文件读写&#xff0c;默认去指定文件进行操作。&#xff08;使用R时&#xff0c;最好先设定工作目录&#xff08;setwd(),getwd()&#xff09;&#xff09; setwd(“工作文件路径”)&#xff1a;建立工作目录 getwd&#xff08;&…

【Mysql数据库基础07】DDL 数据定义语言

Data Definition Language 1 库的操作1.1 create 创建1.2 alter 修改1.3 drop 删除 2 表的操作2.1 表的创建2.2 表的修改2.2.1 修改表名2.2.2 修改列名2.2.3 修改列的类型和约束2.2.4 添加列2.2.5 删除列 2.3 表的删除2.4 表的复制 3 练习 1 库的操作 1.1 create 创建 create…

jvm(虚拟机)运行时数据区域介绍

Java虚拟机&#xff08;JVM&#xff09;运行时数据区域是Java程序在运行过程中使用的内存区域&#xff0c;它主要包括以下几个部分&#xff1a; 程序计数器&#xff08;Program Counter Register&#xff09;&#xff1a; 程序计数器是一块较小的内存区域&#xff0c;是线程私有…

法律合规| AI产品法律风险应对措施全解析

在此前推文中我们全面分析了生成式人工智能算法模型可能遇到的法律风险&#xff0c;那么这些风险应该如何应对呢&#xff1f; 1、隐私泄漏风险&#xff1a;企业需要遵守数据安全法和个人信息保护法的规定&#xff0c;确保数据来源合法&#xff0c;使用时获得用户授权&…

citus的快速开始

准备 dockercitus最新版本&#xff08;docker pull citusdata/citus&#xff09; docker网络 docker network create --subnet172.72.9.0/24 citus-test docker network ls启动citus服务 启动协调节点 docker run -dit --name citus-cod -p 5433:5432 -e POSTGRES_PASSWOR…

【vue3学习之路(一)】

文章目录 前言一、vue3项目创建1.1环境准备1.1.1 基于 vue-cli 创建&#xff08;脚手架创建&#xff09;1.1.2 基于 vite 创建&#xff08;推荐&#xff09; 二、熟悉流程总结 前言 参考视频&#xff1a;https://www.bilibili.com/video/BV1Za4y1r7KE?p10&spm_id_frompag…

使用uniapp 的 plus.sqlite 操作本地数据库报错:::table xxx has no column named xxxx

背景&#xff1a; 1、使用uniapp 的 plus.sqlite 进行APP本地数据库操作 2、SQLite 模块用于操作本地数据库文件&#xff0c;可实现数据库文件的创建&#xff0c;执行SQL语句等功能。 遇到&#xff1a;在之前创建的表上进行新增字段的操作时候&#xff0c;出现问题&#xff1a…

MyEclipse打开文件跳转到notepad打开问题

问题描述 windows系统打开README.md文件&#xff0c;每次都需要右键选择notepad打开&#xff0c;感觉很麻烦&#xff0c;然后就把README.md文件打开方式默认选择了notepad&#xff0c;这样每次双击就能打开&#xff0c;感觉很方便。 然后某天使用MyEclipse时&#xff0c;双击RE…

java第一次作业(二)

先写思路&#xff0c;再写代码&#xff0c;思路清晰&#xff0c;才能写对代码 7-6 求12...n的和 思路&#xff1a; 运用expression的字符串输出 重点&#xff1a; expression输出 代码&#xff1a; import java.util.Scanner; public class Main {public static void main…

数据运营常用的8大模型

✅作者简介&#xff1a;《数据运营&#xff1a;数据分析模型撬动新零售实战》作者、《数据实践之美》作者、数据科技公司创始人、多次参加国家级大数据行业标准研讨及制定、高端企培合作讲师。 &#x1f338;公众号&#xff1a;风姑娘的数字视角&#xff0c;免费分享数据应用相…

为什么静态成员函数不能是虚函数

在面向对象编程中&#xff0c;静态成员函数和虚函数都是常见的概念&#xff0c;但它们之间存在着本质上的差异。由于其特性上的差异&#xff0c;静态成员函数不能声明为虚函数。下面我们来探讨一下为什么静态成员函数不能是虚函数。 我在网上查到最多的说法是静态函数没有this指…

数字化转型能给企业创造哪些价值?

企业数字化转型能创造哪些价值&#xff1f; 深耕TOB行业 9 年&#xff0c;下面来分享下自己的一些经验和看法。 &#xff08;看完要是觉得有用&#xff0c;记得点个赞哈~&#xff09; 1、从宏观上理解&#xff0c;我们可以分成4个大的方面&#xff1a; &#xff08;1&#x…