【力扣-字符串】2、替换空格(05)

340 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

剑指 Offer 05. 替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:

输入: s = "We are happy."
输出: "We%20are%20happy."

暴力法

定义一个新的字符串str,遍历原字符串s,遇到空格就拼接 "%20"字符串 ,如果非空格字符,直接将其拼接到新字符串str的末尾 。方法的效率比较低 代码

class Solution
{
public:
    string replaceSpace(string s)
    {
        // 定义一个空字符串
        string str = "";
        for (int i = 0; i < s.size(); i++)
        {
            // 遍历判断是否是空格
            // 是空格的话就直接append %20
            if (s[i] == ' ')
            {
                str.append("%20");
            }
            else
            {
                // 不是空格的话就将该字符添加到字符串的末尾
                str.push_back(s[i]);
            }
        }

        return str;
    }
};

image.png

双指针法

设置左右指针,从后向前遍历的同时进行字符的移动。之所以从后向前是为了避免每次添加新字符后都需要将其后面的字符移动。 算法步骤:

  1. 确定空格的数量
  2. 扩充字符串的大小
  3. 定义左右指针
  4. 左指针指向原数组的末尾,右指针指向新数组的末尾
  5. 左指针从后向前遍历
  6. 左指针遇到非空格的字符,直接将其移动到右指针的位置
  7. 左指针遇到空格字符时,将右指针及其前面两个位置的字符替换成%20

代码

class Solution
{
public:
    string replaceSpace(string s)
    {
        // 记录空格的数量
        int count = 0;
        int oldSize = s.size();
        for (int i = 0; i < oldSize; i++)
        {
            if (s[i] == ' ')
            {
                count++;
            }
        }
        // 扩充原数组的大小为替换空格为“%20”后的大小
        // 这里的空格数量为 count
        // 每个空格会多出两个字符,所以空间增大了 count * 2
        s.resize(oldSize + count * 2);
        int newSize = s.size();
        for (int j = newSize - 1, i = oldSize - 1; i >= 0, j > i; j--, i--)
        {
            // 如果左指针指向的字符不是空格,将其移到右指针指向的位置
            if (s[i] != ' ')
            {
                s[j] = s[i];
            }
            else
            {
                // 当左指针指向的字符是空格时,
                // 将右指针指向的位置及其前面两个位置共三个位置替换成 %20
                s[j] = '0';
                s[j - 1] = '2';
                s[j - 2] = '%';
                // 将右指针左移两个位置
                j -= 2;
            }
        }
        return s;
    }
};

image.png