【算法专场】模拟(上)
目录
前言
模拟算法
1576. 替换所有的问号
495. 提莫攻击
1688. 比赛中的配对次数
6. Z 字形变换
前言
我们在有时候会看到刷题网站上面看到一些已经把题意讲的很明确的题目,并且一般这种不怎么需要利用那些复杂的算法,只需要我们按照着题目的意思就能够写出来,这种就是---模拟算法。
模拟算法
模拟算法本质上就是比葫芦画瓢。
我们只需要根据题目要求即可解答,但需要注意细节。
一般模拟的过程,我们需要在草稿纸上进行模拟,考虑某些细节问题,在模拟完之后根据演算的过程将代码一步步写出来。
接下来我们来练习一下
1576. 替换所有的问号
通过上面的板书,那么我们就可以将演算的过程转化为以下代码:
class Solution {
public String modifyString(String ss) {
// 将字符串转为字符数组
char[] s = ss.toCharArray();
// 获取zifushu
int n = s.length;
for (int i = 0; i < n; i++) {
// 判断字符是否是问号
if (s[i] == '?') {
// 遍历字符,判断是否有满足条件的
for (char ch = 'a'; ch <= 'z'; ch++) {
// 如果是在第一个字符或者最后一个字符,特殊处理
if ((i == 0 || s[i - 1] != ch) && (i == n - 1 || s[i + 1] != ch)) {
s[i] = ch;
// 替换完毕,停止循环
break;
}
}
}
}
// 返回字符串
return String.valueOf(s);
}
}
时空复杂度为O(n),n为字符串长度。
495. 提莫攻击
将图中的演算过程转化为代码:
class Solution {
public int findPoisonedDuration(int[] timeSeries, int duration) {
//用来存储最终结果
int ans=0;
//遍历,从1开始
for(int i=1;i<timeSeries.length;i++){
int x=timeSeries[i]-timeSeries[i-1];
if(x>=duration) ans+=duration;
else ans+=x;
}
return ans+duration;
}
}
1688. 比赛中的配对次数
将上述转换为代码:
class Solution {
public int numberOfMatches(int n) {
int ans=0;
while(n!=1){
if(n%2==1){//奇数,比赛次数为(n-1)/2
sum+=(n-1)/2;
n=(n-1)/2+1;
}else{//偶数,比赛次数为n/2
sum+=n/2;
n/=2;
}
}
return ans;
}
}
6. Z 字形变换
将上述转换为代码:
/**
* 将给定的字符串按照Z字形排列后,按行读取并返回结果字符串
* Z字形排列是指字符串在numRows行中按顺序排列,第一行和最后一行除外,其它行在两端对齐
* 例如,"PAYPALISHIRING"在3行中按Z字形排列后,按行读取的结果是"PAHNAPLSIIGYIR"
*
* @param s 输入的字符串
* @param numRows 字符串排列的行数
* @return 按Z字形排列后按行读取的字符串
*/
public String convert(String s, int numRows) {
// 判断特殊情况,如果行数为1,直接返回原字符串
if (numRows == 1) return s;
// 创建一个字符串
StringBuffer sb = new StringBuffer();
// 获取输入字符串的长度
int n = s.length();
// 公差,用于计算每个字符在字符串中的位置增量
int d = numRows * 2 - 2;
// 处理第一行
for (int i = 0; i < n; i += d) {
sb.append(s.charAt(i));
}
// 处理中间行
for (int k = 1; k < numRows - 1; k++) {
for (int i = k, j = d - k; i < n; i += d, j += d) {
sb.append(s.charAt(i));
if (j < n) {
sb.append(s.charAt(j));
}
}
}
// 处理最后一行
for (int i = numRows - 1; i < n; i += d) {
sb.append(s.charAt(i));
}
// 将字符串缓冲区转换为字符串并返回
return sb.toString();
}
以上就是模拟上篇的全部内容咯~
若有不足,欢迎指正~