2021.10.3第261场周赛
2027. 转换字符串的最少操作次数
思路
从前往后遍历一遍,如果当前字符为X,进行转换,转换一个改变三个字符
代码
class Solution {
public:
int minimumMoves(string s) {
int ans = 0;
int n = s.size();
for (int i = 0; i < n; i ++ ) {
if (s[i] == 'X') {
ans ++ ;
s[i] == 'O';
if (i + 1 < n)
s[i + 1] = 'O';
if (i + 2 < n)
s[i + 2] = 'O';
}
}
return ans;
}
};
2028. 找出缺失的观测数据
思路
目的是构造一个长度为 n 的序列,使这个序列的和为给定的值 sum,且序列的值在[1, 6]之间
若 sum 小于 1 * n 或大于 6 * n,该序列不存在
否则给每个值赋初值为 1,随后按照应赋尽赋进行其他的值的安排
代码
class Solution {
public:
vector<int> missingRolls(vector<int>& rolls, int mean, int n) {
int m = rolls.size();
int sum = (m + n) * mean;
for (int x : rolls)
sum -= x;
vector<int> ans;
if (sum < n || sum > n * 6)
return ans;
sum -= n; //给每个值赋初值1
for (int i = 0; i < n; i ++ ) {
if (sum == 0) //为0则赋1
ans.push_back(1);
else {
ans.push_back(min(sum, 5) + 1); //赋不超过6的数
if (sum >= 5)
sum -= 5; //最初都减过1 这里最多减5
else
sum = 0;
}
}
return ans;
}
};
2029. 石子游戏 IX
思路
由于题目只需判断是和是否为3的倍数,故可将所有数模3后记录数量
主要思想:让对手凑成3
先手不能选0,只能选1或2
选1时,序列为1121212…
选2时,序列为22121212…
期间选0不影响顺序
记1和2数量大的数为large,小的为small
此序列必定导致1或2数量不足,此时考虑0的个数的奇偶性,若为偶,先手必胜,条件为small>0
small等于0时可能存在
- 1或2数量为0,对手无法通过1+2凑成3,由于先手必选1或2,对手选0即可,0数量为偶数,交替选完后,石子被选完或者我方选到3个相同,故必败
- 1和2全为0,只能选0,必败
当0的数量时奇数时,先手不一定必败,由于是奇数选完0后双方状态交换,1和2相互抵消后,若剩余的相同数字大于2个,则先手必胜,否则提前选完所有数,先手必败
代码
class Solution {
public:
bool stoneGameIX(vector<int>& stones) {
vector<int> a(3);
for (int x : stones)
a[x % 3] ++ ;
int small = min(a[1], a[2]), large = max(a[1], a[2]);
if (a[0] % 2 == 0) {
if (small > 0)
return true;
return false;
}
else {
if (large - small > 2)
return true;
return false;
}
}
};
2030. 含特定字母的最小子序列
思路
类似 316. 去除重复字母 的思路
用贪心的思想,构造一个单调栈,按照特定情况进行弹栈和压栈操作,具体看注释
代码
class Solution {
public:
string smallestSubsequence(string s, int k, char letter, int repetition) {
int n = s.size();
int all_letter = 0; //当前位及当前位后面letter的数量和
for (char c : s)
if (c == letter)
all_letter ++ ;
string ans;
int cur = 0; //答案序列中letter的数量
for (int i = 0; i < n; i ++ ) {
//弹栈
//如果当前位比栈中最后一位字符更优 且 弹出最后一位字符后仍能满足答案序列的长度k
while (ans.size() && ans.back() > s[i] && (ans.size() - 1 + n - i >= k)) {
//如果要弹出的为目标字符 且 弹出后目标字符的个数无法满足重复次数 此时不能弹出
if (ans.back() == letter && all_letter + cur - 1 < repetition)
break;
//否则可以弹出 并记录答案序列中letter的数量
if (ans.back() == letter)
cur -- ;
ans.pop_back();
}
//记录当前位及当前位后面letter的数量和
if (s[i] == letter)
all_letter -- ;
//压栈
//数量不足时才压栈
if (ans.size() < k) {
//如果当前位为目标字符 压栈
//如果当前位不为目标字符 但答案序列除了能放进缺少的目标字符外还有空余位置 压栈
if (s[i] == letter || (k - ans.size()) > max(0, repetition - cur)) {
ans.push_back(s[i]);
cur += s[i] == letter;
}
}
}
return ans;
}
};
本文介绍了四道算法题目的解题思路和代码实现,包括字符串的最少转换次数、缺失观测数据的寻找、石子游戏的策略分析以及含特定字母的最小子序列的构造。涉及的主要算法思想有贪心、遍历、动态规划等,展示了在不同问题中如何运用编程技巧解决问题。
696

被折叠的 条评论
为什么被折叠?



