【蓝桥杯算法练习】205. 反转字符串中的字符(含思路 + Python / C++ / Java代码)
🧩 题目描述
给定一个字符串 s,请你将字符串中的 英文字母字符反转,但其他 非字母字符保持在原位置,输出处理后的字符串。
示例:
输入:s = "a-bC-dEf-ghIj"
输出:"j-Ih-gfE-dCba"
🧠 解题思路
这道题的关键在于两个点:
- 双指针:从前后同时扫描,只对字母字符进行交换;
- 保留非字母位置:如果当前位置是非字母,跳过该位置。
✏️ 实现步骤:
- 将字符串转换为列表(字符串不可变,需用列表操作);
- 使用两个指针
left和right分别从两端向中间移动; - 若
left指向的不是字母,跳过; - 若
right指向的不是字母,跳过; - 若两者都是字母,则交换它们;
- 最后将列表还原为字符串返回。
✅ Python代码实现
def reverseOnlyLetters(s: str) -> str:
s = list(s)
left, right = 0, len(s) - 1
while left < right:
if not s[left].isalpha():
left += 1
elif not s[right].isalpha():
right -= 1
else:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
return ''.join(s)
示例测试
print(reverseOnlyLetters("a-bC-dEf-ghIj")) # 输出: j-Ih-gfE-dCba
print(reverseOnlyLetters("Test1ng-Leet=code-Q!")) # 输出: Qedo1ct-eeLg=ntse-T!
🔧 C++ 代码实现
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string reverseOnlyLetters(string s) {
int left = 0, right = s.size() - 1;
while (left < right) {
if (!isalpha(s[left])) {
left++;
} else if (!isalpha(s[right])) {
right--;
} else {
swap(s[left], s[right]);
left++;
right--;
}
}
return s;
}
int main() {
string s = "a-bC-dEf-ghIj";
cout << reverseOnlyLetters(s) << endl; // 输出: j-Ih-gfE-dCba
return 0;
}
🔧 Java 代码实现
public class ReverseOnlyLetters {
public static String reverseOnlyLetters(String s) {
char[] chars = s.toCharArray();
int left = 0, right = s.length() - 1;
while (left < right) {
if (!Character.isLetter(chars[left])) {
left++;
} else if (!Character.isLetter(chars[right])) {
right--;
} else {
char tmp = chars[left];
chars[left] = chars[right];
chars[right] = tmp;
left++;
right--;
}
}
return new String(chars);
}
public static void main(String[] args) {
String s = "a-bC-dEf-ghIj";
System.out.println(reverseOnlyLetters(s)); // 输出: j-Ih-gfE-dCba
}
}
📌 复杂度分析
- 时间复杂度: O(n) — 每个字符最多访问一次;
- 空间复杂度: O(n) — 因为需要额外使用字符数组或列表来操作。
🧠 小结
这道题目是蓝桥杯常考的字符串操作题,核心考察:
- 字符分类判断(字母/非字母);
- 双指针技巧;
- 对字符串的原地操作能力。
适合作为字符串+双指针的入门题练习。
如果你觉得这篇文章有帮助,欢迎点赞收藏或关注我!
我会持续更新蓝桥杯 & LeetCode 算法刷题指南 💪