剑指Offer 05:替换空格

剑指Offer 05:替换空格

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

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

思路

如果想把这道题目做到极致,就不要只用额外的辅助空间了!

首先扩充数组到每个空格替换成"%20"之后的大小。

然后从后向前替换空格,也就是双指针法,过程如下:

i指向新长度的末尾,j指向旧长度的末尾。

图片

有同学问了,为什么要从后向前填充,从前向后填充不行么?

从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动。

「其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。」

这么做有两个好处:

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前先后填充元素要来的 每次添加元素都要将添加元素之后的所有元素向后移动。

代码

public class 替换空格 {
    public static void main(String[] args) {
        String s = "hello world";
        String s1 = replaceSpaces(s);
        System.out.println(s1);
    }

    public static String replaceSpaces(String s) {
        //统计字符串中空格的个数
        char[] c = s.toCharArray();
        int count = 0;
        for (int i = 0; i < c.length; i++) {
            if (c[i] == ' ') {
                count++;
            }
        }

        //扩充数组
        char[] newChar = new char[c.length + 2 * count];

        //利用双指针,从后向前遍历
        int oldPoint = c.length;
        int newPoint = newChar.length;
        for (int i = oldPoint-1, j = newPoint-1; j >= 0; i--, j--) {

            if (c[i] != ' ') {
                newChar[j] = c[i];
            } else {
                newChar[j] = '0';
                newChar[j - 1] = '2';
                newChar[j - 2] = '%';
                j -= 2;
            }
        }

        String s1 = new String(newChar);
        return s1;
    }

}

时间复杂度:O(n)
空间复杂度:O(1)

此时算上本题,我们已经做了七道双指针相关的题目了分别是:

posted @ 2021-03-11 10:31  胡木杨  阅读(74)  评论(0)    收藏  举报