模拟算法的介绍

1.替换所有的问号

1576. 替换所有的问号 - 力扣(LeetCode)https://leetcode.cn/problems/replace-all-s-to-avoid-consecutive-repeating-characters/description/模拟算法通俗来说就是比葫芦画瓢,也就是这类题题目中已经说清楚了怎么做,我们把题中过程转化为代码进而解决问题就可以了。该题特点:思路比较简单,主要考察代码能力。因此1.模拟算法流程(一定在演算纸上过一便流程)。2.把流程转换成代码。如 a b c ? b c d,可从前往后扫描数组,当碰到问号时将它替换为别的字符就可以了。替换后的最终字符仅需保证两点:1.不要和前后字符一样。2.只能是小写字母。所以碰到问号时从a到z依次尝试就可以了。下面处理一些细节:? a b ? 若问号在最前面和最后面,仅需判断后一个和前一个就行。下面来实现:

2.提莫攻击

495. 提莫攻击 - 力扣(LeetCode)https://leetcode.cn/problems/teemo-attacking/description/ 若在a秒时发动攻击,在b秒时又发动攻击,持续时间是d,此时仅需看一下a和b的差值x(b-a), 若x大于等于d,说明a到b的总的中毒时间是要累加上的(ret += d)。若x小于d,a点中毒后不能把d秒都中完,a到b的差是实际的中毒时间(ret += x)。如:

下面来实现:

下面来实现。

3.N字形变换

6. Z 字形变换 - 力扣(LeetCode)https://leetcode.cn/problems/zigzag-conversion/description/ 解法一:模拟,那如何模拟?如有 a b c d e f g......,n=4,想要模拟需依赖矩阵。这个矩阵行数和n一致,列数字符串多长就弄多少列,这样肯定是够用的:

接下来模拟过程就是从矩阵左上角(0,0)位置开始填字符串:

假设左上角坐标是(x, y),接下来想往下去就不断 x+1,添一个,直到x到n-1时停止。然后开始斜着往上,就让x-1,y+1,填一个......直到x到0时停止。然后继续开始......最终添完后重新遍历一下矩阵就行了。但这样空间和时间复杂度都很高,接下来想办法把模拟策略做一下优化,大部分模拟的优化方式都是找规律:把每个字符下标填上:

第一行和最后一行规律是一样的,因为中间没数。第一行的特点是第一个字符是从0号开始计数的,接下来一下跳到6,再跳到12,它的跳跃间隔是一样的,把这个间隔设为一个d公差。这个例子中d为6,如果我是第一个字符是0号位的字符,接下来仅需到0+6这个位置找g就行,下一个字符就是在上一个字符下标基础上加6就行,这样就能把第一行的字符都找到了。因为公差d后面也要用到,这看一下公差d等于多少:公差d其实是0~6之间不包括6的元素的个数:

其实是前两列元素个数减2个空格就可以了,因此d=2n-2,这个示例中是2*4-2=6。所以第一行是从0位置开始依次加一个公差,最后一行是从n-1位置开始依次加一个公差。再看中间行:

第一行发现第一个元素依旧是公差为d往后递进,无非是递进的过程中间又多了一个元素,前两个相加刚好是d,然后两者同时向后递进。也就是第k行:(k, d-k) --> (k+d, d-k+d)......直到两数下标大于len就停下来:

换为n=3发现规律也符合:

但n=1时有问题,n=1不用变换是原字符,但d算出来是0,所以n=1特殊处理。下面来实现:

4.外观数列

38. 外观数列 - 力扣(LeetCode)https://leetcode.cn/problems/count-and-say/description/ 解法:模拟+双指针,那如何来解释这个字符串呢?如:

就是从前往后扫描过程中,找到相同部分就解释一下。可借助双指针,left和right开始指向起始位置,right找边界位置:right和left指向位置比较,相同right就移动...:

此时right前一个位置直到left区间里所有元素都是重复的,这个区间元素个数是right - left,解释完后left移到right位置,继续移动指针就可以了,直到right到最后没法移到就完了。下面来实现:

5.数青蛙

1419. 数青蛙 - 力扣(LeetCode)https://leetcode.cn/problems/minimum-number-of-frogs-croaking/description/ 解法:模拟,如:

我们先不管c,从前往后遍历,如果遍历到r字符,仅需看看前面有没有c字符就行。若从前往后扫描到o字符,仅需看看前面有没有r就行。所以我们要时刻关注前面字符出现的情况,还需借助一个哈希表:

时刻记录每个字符出现的情况。重新来看,当遍历到c时,c那标记1,说明有个青蛙叫了c字符:

遍历到r时看前面有没有青蛙叫出c,哈希表看到有,所以把青蛙搬到r那让青蛙喊出r就行:

哈希表中操作是让c--,r++。当又碰到c时因为c是起始位置,直接c位置+1就行:

继续向后走,遍历到o时看看有没有一个青蛙叫出r,哈希表看到有,就把青蛙搬到o处,操作让r位置--,o位置++......:

当到c时,c的位置+1,题目有个要求是青蛙数要最少,k是2说明已有2个青蛙完成了croak的叫法,此时又碰到c可从k哪搬出一个青蛙来叫c,这样才能使叫的青蛙数量最小,所以k--,c++:

当字符串遍历完k里存的数就是最少青蛙,k前面数都是0。若k前有非0元素,说明返回-1。再如图:

当到r时发现前面没有c,说明没青蛙能喊出这个字符,此时返回-1就行。下面总结:遍历到r o a k是找一下前驱字符,看是否在哈希表中存在。若存在前驱个数--,当前字符++,若不存在直接返回-1。遍历到c,是去找最后一个字符是否在哈希表中存在,若存在最后一个字符--,当前字符++,若不存在当前字符++。下面实现:

相关推荐
happymaker06262 小时前
简单LRU的实现(基于LinkedHashMap)
算法·leetcode·lru
会编程的土豆2 小时前
【数据结构与算法】空间复杂度从入门到面试:不仅会算,还要会解释
数据结构·c++·算法·面试·职场和发展
普通网友2 小时前
《算法面试必刷:15 个高频 LeetCode 题(附代码)》
算法·leetcode·面试
_深海凉_2 小时前
LeetCode热题100-搜索二维矩阵
算法·leetcode·矩阵
张槊哲2 小时前
C++ 进阶指南:如何丝滑地理解与实践多线程与多进程
开发语言·c++·算法
代码中介商3 小时前
C语言链表完全指南:从单节点到链表管理
c语言·算法·链表
小小de风呀3 小时前
de风——【从零开始学C++】(四):类和对象(下)
开发语言·c++·算法
aqiu1111114 小时前
[特殊字符]【算法日记 14】数论入门神题:最大公约数与最小公倍数的“乘积守恒定律”
算法
保卫大狮兄4 小时前
一文讲清:仓库管理最核心的10个公式
人工智能·算法·仓库管理