力扣对应题目链接:151. 反转字符串中的单词 - 力扣(LeetCode)
牛客对应题目链接:翻转单词序列_牛客题霸_牛客网 (nowcoder.com)


核心考点 :子串划分,子串逆置。
一、题目一
1、《剑指Offer》对应内容





2、分析题目
不要使用辅助空间,空间复杂度要求为O(1)。不能使用辅助空间之后,那么只能在原字符串上下功夫了。
思考一下,将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了。
解题思路如下:
- 移除多余空格。
 - 将整个字符串反转。
 - 将每个单词反转。
 
举个例子,源字符串为:"the sky is blue "
移除多余空格 : "the sky is blue"
 字符串反转:"eulb si yks eht"
 单词反转:"blue is sky the"
 这样我们就完成了翻转字符串里的单词。
3、代码
//力扣
class Solution {
public:
    void removeExtraSpaces(string& s)
    {
        int slow=0;
        for(int fast=0; fast<s.size(); fast++)
        {
            if(s[fast]!=' ')
            {
                if(slow!=0)
                    s[slow++]=' ';
                while(fast<s.size() && s[fast]!=' ')
                    s[slow++]=s[fast++];
            }
        }
        s.resize(slow);
    }
    string reverseWords(string s) {
        removeExtraSpaces(s);
        reverse(s.begin(), s.end());
        int st=0;
        for(int ed=0; ed<=s.size(); ed++)
        {
            if(ed==s.size() || s[ed]==' ')
            {
                reverse(s.begin()+st, s.begin()+ed);
                st=ed+1;
            }
        }
        return s;
    }
};
//牛客
class Solution {
public:
    string ReverseSentence(string str) {
        reverse(str.begin(), str.end());
        int st=0;
        for(int ed=0; ed<=str.size(); ed++)
        {
            if(ed==str.size() || str[ed]==' ')
            {
                reverse(str.begin()+st, str.begin()+ed);
                st=ed+1;
            }
        }
        return str;
    }
}; 
力扣对应题目链接:LCR 182. 动态口令 - 力扣(LeetCode)
牛客对应题目链接:左旋转字符串_牛客题霸_牛客网 (nowcoder.com)


核心考点 :字符串逆置,循环次数去重。
二、题目二
1、《剑指Offer》对应内容





2、分析题目
(1)思路一(迁移)
保存第一个,剩下的整体前移一个,第一个放在最后,完成一次移动,一次能移动,多次也可以。
(2)思路二(逆置)
局部逆置,再整体逆置。
(3)思路三(双倍字符串,不推荐)
直接从字符串的下标 n 开始往后截取原 pStr.size() 的长度就是要求的结果。
3、代码
//力扣
//方法一
class Solution {
public:
    void leftRotate(string &password)
    {
        char tmp=password[0];
        int len=password.size();
        for(int i=0; i<len-1; i++)
            password[i]=password[i+1];
        password[len-1]=tmp;
    }
    string dynamicPassword(string password, int target) {
        if(password.size()==0 || target==0) return password;
        target%=password.size();
        while(target--)
            leftRotate(password);
        return password;
    }
};
//方法二
class Solution {
public:
    void ReverseString(string& password, int st, int ed)
    {
        while(st<ed)
        {
            char tmp=password[st];
            password[st]=password[ed];
            password[ed]=tmp;
            st++;
            ed--;
        }
    }
    string dynamicPassword(string password, int target) {
        if(password.size()==0 || target==0) return password;
        target%=password.size();
        ReverseString(password, 0, target-1);
        ReverseString(password, target, password.size()-1);
        ReverseString(password, 0, password.size()-1);
        return password;
    }
};
//方法三
class Solution {
public:
    string dynamicPassword(string password, int target) {
        int n=password.size();
        password+=password;
        return password.substr(target, n);
    }
}; 
//牛客
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param str string字符串 
     * @param n int整型 
     * @return string字符串
     */
    void ReverseString(string& str, int st, int ed)
    {
        while(st<ed)
        {
            char tmp=str[st];
            str[st]=str[ed];
            str[ed]=tmp;
            st++;
            ed--;
        }
    }
    string LeftRotateString(string str, int n) {
        if(str.size()==0 || n==0) return str;
        n%=str.size();
        ReverseString(str, 0, n-1);
        ReverseString(str, n, str.size()-1);
        ReverseString(str, 0, str.size()-1);
        return str;
    }
};
                


















