在程序设计中,字符串处理问题屡见不鲜,其中字符串左旋是一种常见操作。今天我们一起来探讨一个经典的左旋转字符串题目,以及一种优雅的解决方案——三步翻转法。
左旋转字符串
题目链接:
题目描述
题目要求将给定字符串 S 从第 K 个位置分割为两个子串并互换位置。例如:
输入:abcde
,K = 2
输出:cdeab
解题的关键在于实现有效的字符串左旋,即将字符串的前 K 个字符移到末尾,形成新的字符串。
分析与思路
左旋转字符串可以通过切分字符串并拼接两部分的方式实现,但这种方法可能会导致大量的内存复制。三步翻转法是一种更加高效的方式,仅需对字符数组进行三次局部翻转即可完成目标操作:
- 将前 K 个字符翻转。
- 将剩余字符翻转。
- 最后对整个字符串再翻转一次。
举例说明
以 abcde
为例:
- 第一步:翻转前 3 个字符,得到
edcba
。 - 第二步:翻转后续字符,得到
edcbb
。 - 第三步:将整个字符串翻转,得到
cdeab
,即我们期望的结果。
代码实现
接下来,我们使用 Java 语言实现三步翻转法。此算法时间复杂度为 O(n),仅需常数级的额外空间,因此在性能和空间占用上都表现优异。
public class LeftRotateString {
public String leftRotateString(String s, int n) {
if (s == null || n <= 0 || n >= s.length()) {
return s;
}
char[] chars = s.toCharArray();
int length = chars.length;
// 第一步:翻转前 n 个字符
reverse(chars, 0, n - 1);
// 第二步:翻转剩余字符
reverse(chars, n, length - 1);
// 第三步:翻转整个字符串
reverse(chars, 0, length - 1);
return new String(chars);
}
private void reverse(char[] chars, int start, int end) {
while (start < end) {
char temp = chars[start];
chars[start] = chars[end];
chars[end] = temp;
start++;
end--;
}
}
}
复杂度分析
三步翻转法的时间复杂度为 O(n),空间复杂度为 O(1)。
总结
左旋转字符串问题可以通过多种方法解决,其中三步翻转法是一种简单而高效的方法。通过局部翻转字符串,我们可以避免大量的内存复制,提高程序的性能。