剑指 Offer 05. 替换空格【3】

难度等级:简单

上一篇算法:

剑指 Offer 53 - II. 0~n-1中缺失的数字【数组】

力扣此题地址:

剑指 Offer 05. 替换空格 - 力扣(LeetCode)

1.题目:替换空格

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

2.解题思路:

  1. 先计算新数组总的长度,由于空格换成 "%20",所以每个空格会额外多出两个字符。所以新的长度 = 原来长度 + 空格数 * 2。

    
  2. 准备两个指针 P1, P2。P1 指向原始字符串的末尾,P2 指向新字符串的末尾。

    
  3. 接下来向前移动指针 P1,逐个把它指向的字符复制到 P2 指向的位置,直到碰到了第一个空格为止。碰到第一个空格后,把 P1 向前移动 1 格,在 P2 之前插入字符串 "%20"。由于 "%20" 的长度为 3, 同时也需要把 P2 向前移动 3 格。

      
  4. 反复操作 3 步骤,当 P1 和 P2 指向同一个位置时,表明所有空格都已经替换完毕。所有的字符都只复制(移动)一次,所以时间复杂度为 O (n)。

3.知识补充:

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

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

而从后向前遍历,只需要移动需要移动的即可。

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

这么做有两个好处:

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

4.代码实现:

public String replaceSpace(StringBuffer str) {
        if(str==null)
            return null;
        int numOfblank = 0;//空格数量
        int len=str.length();
        for(int i=0;i<len;i++){  //计算空格数量
            if(str.charAt(i)==' ')
                numOfblank++;
        }
        str.setLength(len+2*numOfblank); //设置长度
        int oldIndex=len-1;  //两个指针
        int newIndex=(len+2*numOfblank)-1;
        
        while(oldIndex>=0 && newIndex>oldIndex){
            char c=str.charAt(oldIndex);
            if(c==' '){
                oldIndex--;
                str.setCharAt(newIndex--,'0');
                str.setCharAt(newIndex--,'2');
                str.setCharAt(newIndex--,'%');
            }else{
                str.setCharAt(newIndex,c);
                oldIndex--;
                newIndex--;
            }
        }
        return str.toString();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值