替换字符串空格:剑指Offer

问题描述:

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

时间限制:1秒 空间限制:32768K

# -*- coding:utf-8 -*-
class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        # write code here
        s = s.replace(' ','%20') //最简单的python方法
        return s

下面用java实现: StringBuffer

思路:逆序替换,降低时间复杂度

关于逆序降低时间复杂度

方法一:从头到尾遍历,找到空格后,依次将空格后面元素后移两位,插入%20,然后遍历一遍即可完成。由于每次出现空格都需要将后面的所有元素做移动处理,因此这种方法的时间负责度为O(n^2)。

方法二:事先遍历一遍字符串,确定空格的个数,从而确定新字符串的长度,然后从尾部开始,逐一复制原始字符串元素到新的位置上,遇到空格时,新元素中插入0 2 %,原始元素指针后移一个单元即可


空间复杂度为O(1)说明不允许用另一个数组来保存新的字符串,时间复杂度为O(N)则可以通过从尾到头遍历来保证

  • 在原有字符串上更改,需要考虑重新设置长度setLength()。
public class Solution {
    public String replaceSpace(StringBuffer str) {
    	int length = str.length();              //字符串原长度
        int countspace = 0;   
        
        for ( int i = 0 ; i < length ; i ++ ) { //统计空格个数
            if ( str.charAt(i) == ' ') {        //注意不要用 "",python两种都可以,java不行
                countspace++;
            }
        }
        int lengthNew = length + countspace*2; //字符串新长度:每个空格就多出两个字符
        
        str.setLength(lengthNew);              //重新设置字符串长度 .setLength(2)
        
        int index = length - 1;                //新旧字符串索引
        int indexNew = lengthNew - 1;
        
        for ( ; index >= 0 ; index-- ) {
            if ( str.charAt(index) == ' ' ) {         //.charAt(索引) 获取字符
                str.setCharAt( indexNew-- , '0' );    //逆序替换:先换再自减
                str.setCharAt( indexNew-- , '2' );
                str.setCharAt( indexNew-- , '%' );
            } else {
                 str.setCharAt( indexNew-- , str.charAt(index) ); // .setCharAt(位置,替换字符)
            }
        }
        return str.toString();                  
    }
}

比python快

c++跑出来4ms,占用内存 400多k,也是逆序替换的思路敲打

/*
分析
将长度为1的空格替换为长度为3的“%20”,字符差的产度变长。
如果允许我们开辟一个新的数组来存放替换空格后的字符串,
那么这道题目就非常简 单。设置两个指针分别指向新旧字符串首元素,
遍历原字符串,如果碰到空格就在新字符串上填入“%20”,
否则就复制元字符串上的内容。但是如果面试官要求
在原先的字符串上操作,并且保证原字符串有足够长的空间来存放替换后的字符串,
那么我们就得另想方法。
如果从前往后替换字符串,那么保存在空格后面的字符串肯定会被覆盖,
那么我们就考虑从后往前进行替换。
首先遍历原字符串,找出字符串的长度以及其中的空格数量,
根据原字符串的长度和空格的数量我们可以求出最后新字符串的长度。
设置两个指针point1和point2分别指向原字符串和新字符串的末尾位置。
如果point1指向内容不为空格,那么将内容赋值给point2指向的位置,
如果point1指向为空格,那么从point2开始赋值“02%”
直到point1==point2时表明字符串中的所有空格都已经替换完毕。
*/

class Solution {
public:
	void replaceSpace(char *str,int length) { //length为系统规定字符串输出的最大长度,固定为一个常数
        int blankNumber = 0;//空格的数量
        int oldstringLen;//记录原字符串的长度
        //首先遍历原字符串,找出字符串的长度以及其中的空格数量
        for (oldstringLen = 0; str[oldstringLen] != '\0'; oldstringLen++){

            if (str[oldstringLen] == ' ')
                blankNumber++;
        }

        //根据原字符串的长度和空格的数量我们可以求出最后新字符串的长度
        int newstringLen = oldstringLen + blankNumber * 2;//新字符串的长度
        if (newstringLen>length)
            return;
        str[newstringLen] = '\0';//此行很重要,因为原字符串最后一个字符为'\0'

        //设置两个指针point1和point2分别指向原字符串和新字符串的末尾位置
        int point1 = oldstringLen - 1, point2 = newstringLen - 1;//因为'\0'已经手工加到最后新串的最后一个字符,所以减1咯

        while (point1 >= 0 && point2>point1){//两指针相同时,跳出循环

            if (str[point1] == ' '){//如果point1指向为空格,那么从point2开始赋值“02%”
                str[point2--] = '0';
                str[point2--] = '2';
                str[point2--] = '%';
            }
            else    //如果point1指向内容不为空格,那么将内容赋值给point2指向的位置
                str[point2--] = str[point1];

            point1--;//不管是if还是else都要把point1前移,为了下一次的执行

        }
	}
};

猜你喜欢

转载自blog.csdn.net/aasdsfdfsd/article/details/80898771