小U的字符串变换挑战
题目理解:
需要计算最少需要多少次操作才能使得字符串 S 中任意两个相邻的字符都不相同。每次操作可以选择字符串中的一个索引 i,并将 S[i] 这个字符按照字母表的顺序循环右移一位。
数据结构的选择
由于我们只需要遍历字符串并进行字符的修改,因此不需要额外的数据结构。直接在字符串上进行操作即可。
算法步骤
- 初始化计数器:用于记录操作次数。
- 遍历字符串:从第二个字符开始,检查当前字符是否与前一个字符相同。
- 修改字符:如果相同,则将当前字符循环右移一位,并增加计数器。
- 确保修改后的字符与前一个字符不同:如果修改后的字符仍然与前一个字符相同,则继续右移,直到不同为止。
- 返回计数器:遍历结束后,返回计数器的值。
代码演示
int countChanges(std::string S, int n) {
int count = 0;
for (int i = 1; i < n; i++) {
if (S[i] == S[i - 1]) {
S[i] = (S[i] - 'a' + 1) % 26 + 'a';
count++;
// 确保当前字符和前一个字符不相同
while (i > 1 && S[i] == S[i - 1]) {
S[i] = (S[i] - 'a' + 1) % 26 + 'a';
count++;
}
}
}
return count;
}
算法复杂度的分析
- 时间复杂度:
O(n) - 空间复杂度:
O(1)
注意事项
- 在修改字符时,需要确保修改后的字符与前一个字符不同,这可能需要多次右移操作。
- 由于题目要求最少操作次数,因此需要考虑从左到右和从右到左两种遍历方式,取其中较小的操作次数。
基本字符串的转换
题目理解
-
基本字符串:
- 一个由字母
'a'组成的字符串被称为“基本”字符串。
- 一个由字母
-
操作规则:
- 在每次操作中,你可以选择三个索引
i、j和k,其中i < j < k,并且满足S[i]和S[k]都是'a'。 - 然后你可以将
S[j]的字符也设置为'a'。
- 在每次操作中,你可以选择三个索引
-
任务:
- 判断是否可以通过多次执行上述操作,将字符串
S变为一个基本字符串。 - 如果可以,返回
1(或True);否则返回0(或False)。
- 判断是否可以通过多次执行上述操作,将字符串
解题思路
-
初始状态检查:
- 如果字符串
S已经是全'a'组成的字符串,那么直接返回True。
- 如果字符串
-
核心逻辑:
- 遍历字符串
S,记录当前遇到的'a'的位置。 - 当遇到非
'a'字符时,检查是否存在合适的i和k使得i < j < k并且S[i]和S[k]都是'a'。
- 遍历字符串
-
判断可行性:
- 如果在遍历过程中,发现某个非
'a'字符无法通过上述操作变为'a',则返回False。 - 如果遍历结束后,所有字符都可以变为
'a',则返回True。
- 如果在遍历过程中,发现某个非
数据结构选择
- 可以使用一个列表来记录当前遇到的
'a'的位置,方便快速查找合适的i和k。
代码展示
bool solution(int N, const std::string& S) {
// write code here
if(S[0]==S[N-1]&&S[0]=='a')
return true;
return false; // Placeholder return
}
时间复杂度
时间复杂度:O(1)