剑指offer--替换空格

来源:互联网 发布:创盈玻璃优化软件手机 编辑:程序博客网 时间:2024/06/06 23:50

题目:实现一个函数,把字符串中的每个空格替换成”%20”,例如输入”we are happy”则输出”we20%are20% happy”;
常规的思路:
我们遍历这个字符串,没遇到一个空格的时候我们把1个空格替换成3个空格,也就是空格后面的字符向后移两个字节,否则就会把后面的字符覆盖了;
如:我们从头打到尾把”we are happy”中的一个空格替换成两个空格
方案一:遇到空格向后挪两位然后把%20拷贝进去,继续遍历字符串,遇到空格做相同的操作,直到字符串尾.
这里写图片描述
我们发现方案一的做法时间复杂度太高,没遇到空格都要挪动数据,当字符串的长度很长时,效率会很慢,假如一个长度为n的字符串,对于每个空字符串,需要向后移动O(n)个字符,整体来说时间复杂度就是O(n^2);
方案二:
从后向前遍历这个字符串,分别用两个指针p1表示替换前的字符串的末尾.指针p2表示替换后字符串的末尾,.然后指针p1向前移动,逐个把字符拷贝到p2所指的位置,遇到空格停止,遇到第一个空格p1向前移动1格,在p2之前插入”%20”,继续向前遍历,知道所有空格被替换,最后p1和p2指向同一位置.
这里写图片描述

实现:void ReplaceBlack(char *str, int len){    assert(str != NULL&&len > 0);    //OldLend表示原长度    int OldLen = 0;    int CountBlack = 0;//统计空格数    int i = 0;    while (str[i] != '\0')    {        ++OldLen;        if (str[i] == ' ')            ++CountBlack;//空格数        ++i;    }    int NewLen = OldLen + 2 * CountBlack;//新的长度    int IndexOld = OldLen;    int IndexNew = NewLen;    while (IndexOld>=0&&IndexOld>IndexNew)    {        //IndexOld遇到空格停下来,IndexNew前移替换        if (str[IndexOld] == ' ')        {            str[IndexNew--] = '%';            str[IndexNew--] = '0';            str[IndexNew--] = '2';        }        else        {            //把原来的字符串拷贝到新空间            str[IndexNew--] = str[IndexOld];        }        --IndexOld;    }}

同样的如果两个排序数组A1和A2,内存在A1尾部有足够的剩余空间容纳A2,实现一个函数把A2的数据插入到A1当中并且是有序的;
方法和前面类似,如果从头到尾拷贝数据,会多拷贝一次,如何从后向前拷贝效率会更高.

原创粉丝点击