Leetcod每日一题:151.reverse-words-in-a-string(翻转字符串里的单词)

思路是:双指针去头尾空格,然后遍历中间去空格直到每个单词后最多一个空格;然后将整个字符串翻转,然后从头遍历将遇到的单词翻转回去;
在这里插入图片描述
一开始因为while (s[end] == ' ' && end >= 0) //除去结尾空格end>=0不严谨,导致案例" "死活不通过,我以为结果有问题,试了几次才发现end在这个案例中会减到-1,使得s[-1]这种溢出情况出现;

错误原因:Line 1060: Char 9: runtime error: addition of unsigned offset to 0x7ffc46f434a0 overflowed to 0x7ffc46f4349f (basic_string.h)

使用api应该会快些,尤其时java的,这里我就懒得换了;

#include <iostream>
#include <string>
using namespace std;

void reverse(string &s, int begin, int end) //将s[begin] 至 s[end] 字符串部分反转
{
    string re = s.substr(begin, end - begin + 1);
    int k = end - begin;
    for (int i = begin; i <= end; i++) //反转后置回原字符串
    {
        s[i] = re[k--];
    }
}

string reverseWords(string s)
{
    string s_end="";
    if(s.length()==0)  return s_end;

    int begin = 0, end = s.length() - 1; //begin end 用于确定边界

    while (s[begin] == ' ' && begin < s.length()) //除去开头空格
    {
        begin++;
    }
    while (s[end] == ' ' && end > 0) //除去结尾空格
    {
        end--;
    }

    if(begin>=end) return s_end;

    for (int i = begin; i <= end;) //去单词后多余的空格
    {
        s_end.push_back(s[i++]);
        if (s[i] == ' ' && i <= end)
        {
            s_end.push_back(' ');
            while (s[i] == ' ')
                i++;
        }
    }

    reverse(s_end, 0, s_end.length() - 1); //将它全部反转

    //然后遇到一个空格就将前面的单词再反转过来
    int nums = 0;
    int len = s_end.length();
    for (int i = 0; i <= len; i++)
    {
        if (s_end[i] == ' ' || i == len )
        {
            reverse(s_end, i - nums, i - 1);
            nums = 0;
        }
        else
        {
            nums++;
        }
    }
    return s_end;
}

int main()
{
    cout << reverseWords("    hello    world!    ") << endl;
    cout << reverseWords("the sky is blue") << endl;
    cout << reverseWords("a good   example") << endl;
    cout << reverseWords(" ") << endl;
    return 0;
}