目录
- 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];
}