剑指offer面试题5:替换空格(JAVA版已在牛客网AC)

题目

请实现一个函数,把字符串中的每个空格替换成“%20”。例如,输入“We are happy.”,则输出“We%20are%20happy.”。

思路

看到这个问题,我们通常的思路是从前向后遍历字符串,每遇到一个空格将空格之后的字符向后移动两位,然后将将“%20”插进去,假设字符串长度为n,有n个空格,对于每个空格,需要移动后面的字符的时间复杂度为o(n),则对于n个空格时间复杂度为o(n*n);在前面的分析中我们发现数组中很多字符都移动了多次,能不能找一个好方法来减少移动次数呐?接下来我们来看一个时间复杂度为o(n)的算法,把从前向后替换改为从后向前替换。

  1. 我们先遍历一遍字符串,先统计出空格的数量,并可以借此计算出替换后字符串的长度。每替换一个空格,字符串的长度加2,因此替换后的字符串的长度为原来的长度+空格数2;以题目给的样例为例“We are happy.”这个字符串在java中长度为13(java字符串末尾没有‘\0’),里面有两个空格,因此替换后的字符串长度为13+22=17;
  2. 我们开始从字符串的后面开始复制和替换。准备两个索引indexOfOriginal(旧字符串的最后一个字符的下标indexOfNew(替换后的字符串的最后一个字符的下标),然后开始从后(即用indexOfOriginal递减来实现)向前遍历字符串。
  3. 如果indexOfOriginal指向的字符为空格时 ,则将indexOfNew所在的位置赋值为‘0’,然后将indexOfNew向前移动一个位置,将新位置赋值为’2’,继续将indexOfNew向前移动一个位置,将新位置赋值为’%’,继续将indexOfNew向前移动一个位置。此时从后向前的第一个空格替换完成;继续遍历字符串。
  4. 如果indexOfOriginal指向的字符不为空时,直接将该字符赋值给indexOfNew指向的位置,然后将indexOfNew向前移动一个位置。
  5. 重复3和4直到字符串被遍历完。

从上面分析来看,所有的字符都只需要移动一次,因此时间复杂度为o(n).

代码实现(java)

import java.util.Scanner;

/**
 * @author FengTianHao
 * @version 1.0
 * @since 2018/11/30 11:07
 *
 */
public class Test {
    public String replaceSpace(StringBuffer str) {

        if(str==null||str.length()==0)
        {
            return str.toString();
        }
        int numberOfBlank=0;//空格的数量
        for(int i=0;i<str.length();i++)
        {
            if(str.charAt(i)==' ')
            {
                numberOfBlank++;
            }
        }
        int indexOfOriginal=str.length()-1;//指向旧字符串的最后一个字符
        int newlength=str.length()+numberOfBlank*2;//计算新字符串的长度
        str.setLength(newlength);//将旧字符串的空间扩大
        int indexOfNew=str.length()-1;//指向新字符换的最后一个字符
        for(;indexOfOriginal>=0&&indexOfNew>indexOfOriginal;--indexOfOriginal)
        {
            if(str.charAt(indexOfOriginal)==' ')//当前字符为空格时
            {
                str.setCharAt(indexOfNew--,'0');
                str.setCharAt(indexOfNew--,'2');
                str.setCharAt(indexOfNew--,'%');
            }
            else//当前字符不为空格时
            {
                str.setCharAt(indexOfNew--,str.charAt(indexOfOriginal));
            }
        }

        return str.toString();
    }

    public static void main(String[]args) {
        StringBuffer str=new StringBuffer(" We are happy.");
        System.out.println(new Test().replaceSpace(str));
    }
}

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值