一、经验总结
模拟题型的算法原理相对简单,就是依葫芦画瓢:题目中怎样描述,算法就怎样执行。考验的主要是将实际问题转换为代码的能力。
但是模拟题型并不是只能傻乎乎的按步骤编码,也可以先将模拟算法的流程通过举例或绘图演示一遍,再从中总结规律或是利用数学办法进行计算,算法的效率也能得到很大的提升。
二、相关编程题
2.1 替换所有的问号
题目链接
1576. 替换所有的问号 - 力扣(LeetCode)
题目描述
算法原理
编写代码
class Solution {
public:
string modifyString(string s) {
for(size_t 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])
{
continue;
}
else
{
s[i] = ch;
break;
}
}
}
}
return s;
}
};
2.2 提莫攻击
题目链接
495. 提莫攻击 - 力扣(LeetCode)
题目描述
算法原理
编写代码
class Solution {
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration) {
int ret = 0;
for(size_t i = 0; i < timeSeries.size()-1; ++i)
{
int diff = timeSeries[i+1]-timeSeries[i];
if(diff >= duration)
ret += duration;
else
ret += diff;
}
ret+=duration;
return ret;
}
};
2.3 N字形变换
题目链接
6. Z 字形变换 - 力扣(LeetCode)
题目描述
算法原理
编写代码
class Solution {
public:
string convert(string s, int numRows) {
// 处理边界情况
if (numRows == 1)
return s;
int d = 2 * numRows - 2;
int n = s.size();
string ret;
// 处理第一行
for (int i = 0; i < n; i += d)
ret += s[i];
// 处理中间行
for (int k = 1; k < numRows - 1; ++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];
}
}
// 处理最后一行
for (int i = numRows - 1; i < n; i += d)
ret += s[i];
return ret;
}
};
2.4 外观数列
题目链接
38. 外观数列 - 力扣(LeetCode)
题目描述
算法原理
编写代码
//递归
class Solution {
public:
string countAndSay(int n) {
if(n == 1) return "1";
string prev = countAndSay(n - 1);
string ret;
int left = 0, right = 0;
while (right < prev.size()) {
if (prev[left] != prev[right]) {
ret += (right - left) + '0';
ret += prev[left];
left = right;
} else {
++right;
}
}
ret += (right - left) + '0';
ret += prev[left];
return ret;
}
};
//非递归
class Solution {
public:
string countAndSay(int n) {
string ret = "1";
for(int i = 0; i < n-1; ++i)
{
string tmp;
int left = 0, right = 0;
while(right < ret.size())
{
while(right < ret.size() && ret[right] == ret[left])
++right;
tmp += to_string(right-left) + ret[left];
left = right;
}
ret = tmp;
}
return ret;
}
};
2.5 数青蛙
题目链接
1419. 数青蛙 - 力扣(LeetCode)
题目描述
算法原理
编写代码
class Solution {
public:
int minNumberOfFrogs(string croakOfFrogs) {
//将所有得字符映射到数组,方便找到croak中的前一个字符
string str = "croak";
unordered_map <char, int> index;
int n = str.size();
for(int i = 0; i < n; ++i)
{
index[str[i]] = i;
}
//该哈希表用于追踪每只青蛙的croak
vector<int> hash(n, 0);
for(int i = 0; i < croakOfFrogs.size(); ++i)
{
char curi = index[croakOfFrogs[i]];
if(curi == 0)
{
if(hash[n-1] != 0) --hash[n-1];
++hash[curi];
}
else
{
if(hash[curi-1] == 0) return -1; //存在无效的croak
--hash[curi-1];
++hash[curi];
}
}
//检查无尾的croak
for(int i = 0; i < n-1; ++i)
{
if(hash[i] != 0) return -1; //存在无效的croak
}
return hash[n-1];
}
};