[剑指Offer]:左旋转字符串

57 阅读1分钟

文章目录


题目描述

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:

输入: s = "abcdefg", k = 2
输出: "cdefgab"

示例 2:

输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"

题解思路

方法一:逐个添加、删减

  1. 我们不断向 s 的末尾用 += 来添加 [0, n] 区间内的元素,添加完后再 erase 掉该元素。
  2. 第一个想到的思路就是这个了,执行用时不理想应该是每次循环都要调用 erase() 函数。

代码实现:

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        if(n >= s.length() || s.length() < 2 || n == 0) return s;
        
        int count = 0;
        while(count < n){
            s += s[0];
            s.erase(0, 1);
            count++;
        }
        return s;
    }
};

方法二:三次翻转

  1. 我们把需要向左旋转的字符串部分叫做 s1,剩余不用处理的部分叫做 s2,所以有: s = s1 + s2。假设 s = “abcdefg”, k = 2。那么 s1 = “ab”,s2 = “cdefg”。
  2. 翻转 s1,则有:s1 = “ba”,s = “bacdefg”。
  3. 再翻转 s2,则有:s2 = “gfedc”,s = “bagfedc”。
  4. 最后翻转整个 s,则有:s = “cdefgab”。

代码实现:

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        if (n >= s.length() || s.length() < 2 || n == 0) {
            return s;
        }

        reverse(s, 0, n - 1);   // 翻转 s1 部分
        reverse(s, n, s.length() - 1);  // 翻转 s2 部分
        reverse(s, 0, s.length() - 1);  // 翻转整个字符串 s

        return s;
    }

    void reverse(string& s, int start, int end) {
        if (end >= s.length() || end - start < 1) {
            return;
        }

        while (start < end) {
            char temp = s[start];
            s[start] = s[end];
            s[end] = temp;
            start++; end--;
        }
    }
};

如有帮助到您,可以多多点赞、评论鼓励哟~~~