剑指offer之面试题4:替换空格

来源:互联网 发布:私人影院点播软件 编辑:程序博客网 时间:2024/05/01 18:41

题目描述

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

思路:看到这个题目,想到一个问题,就是一个空格字符,替换之后编程“%20”三个字符,字符串长度变长,如果在原字符串上替换,会产生覆盖、越界。
如果创建新的字符串,我们可以为它分配较大内存,然后遍历原字符串并逐个复制到新字符串中,遇到空格,复制“%20”,直到原字符串遍历到末尾,结束。

下面考虑在原字符串上做替换,并假设字符串末尾有足够多的空余内存。
直观做法:从头遍历,遇到空格替换,将之后的所有字符后移两位。假设字符串长度n,对每个空格,需要移动后面O(n)个字符,若有O(n)个空格,则时间复杂度为O(n^2)

时间效率之所以这么高是因为,含重复移动,是否可以一次移动到位,减少重复移动,从而提高效率?

如果事先确定替换后的字符串长度,然后从字符串末尾开始替换,这样替换后的位置就是最终位置,只需要复制即移动一次(O(1)时间内可完成),这样整个时间复杂度为O(n)。

具体思路:先遍历一遍字符串,统计空格数目,计算出来替换后字符串所需长度(原来的length+2*numberOfBlanks)。定义两个指针,分别指向原来字符串末尾和替换后的字符串末尾,然后末尾往前遍历,并将原来字符串指针指向的字符,逐个复制到替换后字符串的指针指向的位置,当遇到空格时,用StringBuffer的replace(int start, int end, String str) 函数替换,当两个指针指向的位置相同时,说明空格都已替换完毕,结束

下面贴上代码(牛客OJ提交成功)

import java.lang.*;public class Solution {    public static String replaceSpace(StringBuffer str) {        //StringBuilder和StringBuffer等同,后者效率较低,用于多线程        if(str==null||str.length()<0)            return null;        //count the number of spaces in the str        int numberOfBlank=0;        for(int i=0;i<str.length();i++){            if(str.charAt(i)==' '){                numberOfBlank++;            }        }        int newLength=str.length()+2*numberOfBlank;        int indexOfOriginal=str.length()-1;        int indexOfNew=newLength;        str.setLength(50);//字符数组后面可用空间        while(indexOfOriginal>=0&&indexOfNew>indexOfOriginal){            if(str.charAt(indexOfOriginal)==' '){                str.replace((indexOfNew=indexOfNew-3),(indexOfNew+3),"%20");            }            else{                //indexOfNew--;                str.setCharAt(indexOfNew=indexOfNew-1,str.charAt(indexOfOriginal));            }            indexOfOriginal--;        }//end while        return str.toString().trim();    }    public static void main(String[] args){        StringBuffer str=new StringBuffer();        str.append("we are happy");        System.out.println(replaceSpace(str));    }}
0 0
原创粉丝点击