在程序设计中,字符串处理问题屡见不鲜,其中字符串左旋是一种常见操作。今天我们一起来探讨一个经典的左旋转字符串题目,以及一种优雅的解决方案——三步翻转法。

左旋转字符串

题目链接:

题目描述

题目要求将给定字符串 S 从第 K 个位置分割为两个子串并互换位置。例如:

输入:abcde,K = 2

输出:cdeab

解题的关键在于实现有效的字符串左旋,即将字符串的前 K 个字符移到末尾,形成新的字符串。

分析与思路

左旋转字符串可以通过切分字符串并拼接两部分的方式实现,但这种方法可能会导致大量的内存复制。三步翻转法是一种更加高效的方式,仅需对字符数组进行三次局部翻转即可完成目标操作:

  1. 将前 K 个字符翻转。
  2. 将剩余字符翻转。
  3. 最后对整个字符串再翻转一次。

举例说明

abcde 为例:

  1. 第一步:翻转前 3 个字符,得到 edcba
  2. 第二步:翻转后续字符,得到 edcbb
  3. 第三步:将整个字符串翻转,得到 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)。

总结

左旋转字符串问题可以通过多种方法解决,其中三步翻转法是一种简单而高效的方法。通过局部翻转字符串,我们可以避免大量的内存复制,提高程序的性能。