LeetCode151.翻转字符串里的单词—双指针的应用

LeetCode151.翻转字符串里的单词—双指针的应用_第1张图片

思路:

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转

仅以移除多余空格为例,最初的思路很容易写出

    void removeExtraSpace(string& s) {
        //剔除字符串中间多余的空格
        for (int i = s.size() - 1; i > 0; i--) {
            if (s[i] == s[i - 1] && s[i] == ' ') {
                s.erase(s.begin() + i);
            }
        }
        //剔除字符串最后面的空格
        if (s.size() > 0 && s[s.size() - 1] == ' ') {
            s.erase(s.begin() + s.size() - 1);
        }

        //剔除字符串最前面的空格
        if (s.size() > 0 && s[0] == ' ') {
            s.erase(s.begin());
        }
    }

因为erase本身就是O(n)的操作,再加上外面嵌套了一个for循环,那么整体的时间复杂度就变为O(n^2).

若考虑双指针发来移除空格,最后resize字符串的大小,可达到O(n)的时间复杂度

// 移除冗余空格,使用双指针
    void removeExtraSpace(string& s) {
        int slowIndex = 0, fastIndex = 0; // 定义快慢指针
        //去掉字符串前面的空格
        while (s.size() > 0 && fastIndex < s.size() && s[fastIndex] == ' ') {
            fastIndex++;
        }
        
		//去掉字符串中间部分的冗余空格
        for (; fastIndex < s.size(); fastIndex++) {
            if (fastIndex - 1 > 0 && s[fastIndex - 1] == s[fastIndex] && s[fastIndex] == ' ') {
                continue;
            } else {
                s[slowIndex++] = s[fastIndex];
            }
        }
        
		//去掉字符串末尾可能出现的单个空格
        if (slowIndex - 1 > 0 && s[slowIndex - 1] == ' ') 
        {
            s.resize(slowIndex - 1);
        } else {
            s.resize(slowIndex); //重新设置字符串大小
        }
    }

完整代码如下:

class Solution {
public:
    //反转字符串中s中左闭右闭的区间[start,end]
    void reverse(string& s, int start, int end) {
        for (int i = start, j = end; i < j; i++, j--) {
            swap(s[i], s[j]);
        }
    }
    // 移除冗余空格,使用双指针
    void removeExtraSpace(string& s) {
        int slowIndex = 0, fastIndex = 0; // 定义快慢指针
        //去掉字符串前面的空格
        while (s.size() > 0 && fastIndex < s.size() && s[fastIndex] == ' ') {
            fastIndex++;
        }

        for (; fastIndex < s.size(); fastIndex++) {
            //去掉字符串中间部分的冗余空格
            if (fastIndex - 1 > 0 && s[fastIndex - 1] == s[fastIndex] && s[fastIndex] == ' ') {
                continue;
            } else {
                s[slowIndex++] = s[fastIndex];
            }
        }

        if (slowIndex - 1 > 0 && s[slowIndex - 1] == ' ') //去掉字符串末尾可能出现的单个空格
        {
            s.resize(slowIndex - 1);
        } else {
            s.resize(slowIndex); //重新设置字符串大小
        }
    }

    string reverseWords(string s) {
        removeExtraSpace(s);         //去掉冗余空格
        reverse(s, 0, s.size() - 1); //将字符串全部反转
        // 快慢指针法反转局部单词
        int fastIndex = 0, slowIndex = 0;
        for (fastIndex = 0; fastIndex < s.size() - 1; fastIndex++) {
            if (s[fastIndex] == ' ') {
                reverse(s, slowIndex, fastIndex - 1);
                slowIndex = fastIndex + 1;
            }
        }
        //最后一个单词
        reverse(s, slowIndex, s.size() - 1);
        return s;
    }
};

你可能感兴趣的:(算法与数据结构,二分法)