目录
- 0.原理讲解
- 1.替换所有的问号
- 1.题目链接
- 2.代码实现
- 2.提莫攻击
- 1.题目链接
- 2.算法原理详解
- 3.代码实现
- 3.N 字形变换
- 1.题目链接
- 2.算法原理详解
- 3.代码实现
- 4.外观数列
- 1.题目链接
- 2.算法原理详解
- 3.代码实现
- 5.数青蛙
- 1.题目链接
- 2.算法原理详解
- 3.代码实现
0.原理讲解
- 模拟:依照题目要求,照葫芦画瓢
:P
- 如果模拟题的时间复杂度和空间复杂度过高,则一般都需要进行优化
- 优化:一般都是找规律
1.替换所有的问号
1.题目链接
- 替换所有的问号
2.代码实现
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 == n - 1 || ch != s[i + 1]))
{
s[i] = ch;
}
}
}
}
return s;
}
2.提莫攻击
1.题目链接
- 提莫攻击
2.算法原理详解
- 计算相邻两个时间点的差值:
- 如果差值⼤于等于中毒时间,说明上次中毒可以持续
duration
秒 - 如果差值⼩于中毒时间,那么上次的中毒只能持续两者的差值
- 如果差值⼤于等于中毒时间,说明上次中毒可以持续
3.代码实现
int FindPoisonedDuration(vector<int>& timeSeries, int duration)
{
int ret = 0;
for(int i = 1; i < timeSeries.size(); i++)
{
int interval = timeSeries[i] - timeSeries[i - 1];
if(interval >= duration)
{
ret += duration;
}
else
{
ret += interval;
}
}
return ret + duration;
}
3.N 字形变换
1.题目链接
- N 字形变换
2.算法原理详解
- 本题可以照本宣科的按照要求存储 && 读取,但是此时时间复杂度和空间复杂度都很高
- 模拟题优化:找规律
3.代码实现
string Convert(string s, int numRows)
{
// 处理边界情况
if(numRows == 1)
{
return s;
}
string ret;
int n = s.size(), d = 2 * numRows - 2;
// 第一行
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;
}
4.外观数列
1.题目链接
- 外观数列
2.算法原理详解
- 思路:模拟 + 双指针
3.代码实现
// 控制逻辑 v1.0
// 自己控代码的逻辑
string CountAndSay(int n)
{
string src = "1";
for(int i = 2; i <= n; i++) // 控制行
{
// 双指针
string ret;
int left = 0, right = 0;
for(; right < src.size(); right++)
{
if(src[left] != src[right])
{
ret += to_string(right - left) + src[left];
left = right;
}
}
// 处理最后的一组数
ret += to_string(right - left) + src[left];
src = ret;
}
return src;
}
--------------------------------------------------
// 控制逻辑 v2.0
// 此逻辑比较优秀,不需求额外处理结尾情况
string CountAndSay(int n)
{
string src = "1";
for(int i = 2; i <= n; i++) // 控制行
{
// 双指针
string ret;
for(int left = 0, right = 0; right < src.size();)
{
while(right < src.size() && src[left] == src[right])
{
right++;
}
ret += to_string(right - left) + src[left];
left = right;
}
src = ret;
}
return src;
}
5.数青蛙
1.题目链接
- 数青蛙
2.算法原理详解
-
用哈希表来存储叫声
3.代码实现
int MinNumberOfFrogs(string croakOfFrogs)
{
string str = "croak";
int n = str.size();
vector<int> hash(n); // 用数组模拟哈希
unordered_map<char, int> index; // <ch, index>
for(int i = 0; i < n; i++)
{
index[str[i]] = i;
}
for(auto& ch : croakOfFrogs)
{
if(ch == 'c')
{
if(hash[n - 1]) // k已存在
{
hash[n - 1]--;
}
hash[0]++;
}
else
{
int i = index[ch];
if(hash[i - 1] == 0)
{
return -1;
}
hash[i - 1]--;
hash[i]++;
}
}
for(int i = 0; i < n - 1; i++)
{
if(hash[i] != 0)
{
return -1;
}
}
return hash[n - 1];
}