思路:

题目的要求:

  • 限制时间为O(n)
  • 将字符串大小写反转,这个遍历字符串即可,也在O(n)以内
  • 反转单词的位置

方法一:双逆转 具体做法:

  • 第一次反转整个字符串,这样基本的单词逆序就有了,但是每个单词的字符也是逆的
  • 第二次遍历字符串的同时反转每个单词

图片说明

class Solution {
public:
    string trans(string s, int n) {
        if(n==0) 
            return s;
        string res;
        for (int i = 0; i < n; i++)
        {
             if (s[i] <= 'Z' && s[i] >= 'A')   //大小写转换
                 res += s[i] - 'A' + 'a';
             else if (s[i] >= 'a' && s[i] <= 'z') 
                 res += s[i] - 'a' + 'A';
             else 
                 res+=s[i];  //空格直接复制
        } 
        reverse(res.begin(), res.end());  //翻转整个字符串
        for (int i = 0; i < n; i++)
        {
            int j = i;
            while(j < n && res[j] != ' ')  //以空格为界,二次翻转
                j++;
            reverse(res.begin() + i, res.begin() + j); 
            i = j;
        }
        return res;
    }
};

复杂度分析:

  • 时间复杂度:O(n),虽有多个循环,但是每个循环都只有一层O(n)
  • 空间复杂度:O(n),res是存储变换的临时字符串,也可以直接用s直接变换,这样就为O(1)

方法二:分割字符串+栈 因此题目要求将单词逆序, 于是可以相当按照空格把字符串分割成一个个单词,存入栈中,因此栈遵循先进后出的原理,所以可以做到单词逆序。 图片说明

class Solution {
public:
    string trans(string s, int n) {
        if(n==0) 
            return s;
        string res;
        for (int i = 0; i < n; i++)
        {
             if (s[i] <= 'Z' && s[i] >= 'A')   //大小写转换
                 res += s[i] - 'A' + 'a';
             else if (s[i] >= 'a' && s[i] <= 'z') 
                 res += s[i] - 'a' + 'A';
             else 
                 res+=s[i];  //空格直接复制
        }
        stack<string> temp;
        for (int i = 0; i < n; i++)
        {
            int j = i;
            while(j < n && res[j] != ' ')  //以空格为界,分割单词
                j++;
            temp.push(res.substr(i, j - i));  //单词进栈
            i = j;
        }
        if(s[n - 1] == ' ')  //排除结尾空格的特殊情况
            res = " ";
        else
            res = "";
        while(!temp.empty()){   //栈遵循先进后厨,单词顺序是反的
            res += temp.top();
            temp.pop();
            if(!temp.empty())
                res += " ";
        }
        return res;
    }
};

复杂度分析:

  • 时间复杂度:O(n),所有循环最多遍历一次

  • 空间复杂度:O(n),栈空间