我们都遇到过的 Replace Blank Space

题目描述:

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

分析:  看到这个题目,我们都会有一个比较直观的加法,那就是遍历字符串,每当遇到空格,就在当前位置插入“%20”,当前位置的字符往后移动三个位置。接着继续遍历,直到字符串结束。这个解法简单容易理解,但是直观的解法往往是效率比较低的,不难看出这个算法的时间复杂度是O(n^2).    那么接下来就来看一下时间复杂度为O(n)的算法。不难看出无论什么算法都得遍历一遍整个字符串,那么既然从前往后遍历字符串效率低,那么我们就从后面往前遍历又会如何呢?这个算法需要两次遍历字符串。第一次从前往后遍历字符串,统计字符串中空格的次数。然后计算出把空格替换成“%20”后的字符串长度。然后就进行第二次遍历字符串,准备两个指针p1、p2,p1指向替换前字符串的末尾,p2指向替换后字符串的末尾,然后往前开始遍历数组,逐个把p1指向的字符复制到p2指向的地址。当遇到p1遇到空格时,p1向前移动一步,在p2前面插入三个字符“%20”,p2向前移动三步,接着又开始一步一步往前遍历替换,遇到空格时执行前面同样的操作。直到遍历结束。    如果我说得不是很清楚,请看实现代码吧!

C++实现:

 1 class ReplaceBlankSpace {
 2 public:
 3     void replaceSpace(char *str,int length) {
 4         int spaceNum = 0;
 5         int origin = length - 1;
 6         int end = 0;
 7         for (int i = 0; i < length; i++)
 8     {
 9             if (str[i] == ‘ ‘)
10       {
11                 spaceNum++;
12       }
13     }
14
15         int afterLength = length + spaceNum * 2 - 1 ;
16         end = afterLength;
17         for (int i = length - 1 ; i >= 0 ; i -- )
18     {
19             if (str[i] == ‘ ‘)
20       {
21                 str[afterLength] = ‘0‘;
22                 str[afterLength -1] = ‘2‘;
23                 str[afterLength -2] = ‘%‘;
24                 afterLength -= 3;
25       }
26             else
27       {
28                 str[afterLength] = str[i];
29                 afterLength --;
30       }
31     }
32
33   }
34 };

总结:

  直观的算法之所以效率低,是因为需要多次重复移动空格后面的字符。而第二种算法从后面遍历字符串就避免的多次重复移动字符,所有字符串都只复制移动了一次,所以时间复杂度是O(n),从而提高了效率。

  以此类推,如果我们遇到的的算法题,从前往后遍历需要多次重复复制移动元素,那么久可以考虑一下,是否可以从后往前遍历,减少复制移动的次数,从而提高效率。

时间: 2024-11-08 19:23:51

我们都遇到过的 Replace Blank Space的相关文章

blank space in latex math environment

\quad takes its name from this traditional name; \qquad just means ”two quads”. However in TeX the \quad has no height, but only width.

Solr相似度名词:VSM(Vector Space Model)向量空间模型

最近想学习下Lucene ,以前运行的Demo就感觉很神奇,什么原理呢,尤其是查找相似度最高的.最优的结果.索性就直接跳到这个问题看,很多资料都提到了VSM(Vector Space Model)即向量空间模型,根据这个模型可以对搜索的结果进行最优化的筛选,目前还不知道如何证明,只能凭借想象应该是这个样子的. 1.看一下TF/IDF 我们先来看下一个叫TF/IDF的概念,一般它用来作为一个搜索关键字在文档或整个查询词组的权重的计算方式.前几天看了吴军老师的数学之美系列文章,这个TF/IDF可以追

Replace 删除、替换函数精解示例

'************************************************************************* '**模 块 名:Replace函数精解示例 '**说    明:蓝凤凰设计商城 浴火凤凰-郭卫 | 蓝凤凰-魔灵 | 郭卫-icecept '**创 建 人:浴火凤凰-郭卫 '**日    期:2015年10月11日  12:00:13 '**修 改 人:浴火凤凰-郭卫 '**日    期: '**描    述:QQ:493405998 | 微信

正则表达式和文本处理工具

一 什么是正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 生活中处处都是正则:     比如我们描述:4条腿      你可能会想到的是四条腿的动物或者桌子,椅子等     继续描述:4条腿,活的           就只剩下四条腿的动物这一类了 在linux中,通配符是由shell解释的,而正则表达式则是由命令解释的,下面我们就为大家介绍三种文本处理工具/命令:grep.sed.awk,它们三者均可以解释正

oracle ocp知识点

1.如何确定数据库是否启动 su - oracle ps -ef |grep ora_|head -2 两种关系数据库是ora或者是自动存储管理的asm开头的, 查看进程可以知道数据库实例至少已经启动,但是数据库是否挂载,是否打开,不得而知 asm crs_stat -t updb.db online srvctl status database -d updb db sqlplus  -s / as sysdba select open_mode from database; 通过查询该视图可

[转]Delphi 快捷键 让你更像高手!!

新一篇: IDFTP 控件使用 >>代码模板 : CTRL+J >>代码整块移动 : CTRL+SHIFT+I(右移) CTRL+SHIFT+U(左移)>>选中窗体 : 先选中任一控件,SHIFT+鼠标左键>>将鼠标指向变量名.单元名.类名,再用 CTRL+鼠标左键 可找到相应的说明>>在过程.函数.事件内部, SHIFT+CTRL+向上的方向键  可跳跃到相应的过程.函数.事件的定义 相反,在过程.函数.事件的定义处,SHIFT+CTRL+向下

【oracle ocp知识点一】

1.怎样确定数据库是否启动 su - oracle ps -ef |grep ora_|head -2 两种关系数据库是ora或者是自己主动存储管理的asm开头的, 查看进程能够知道数据库实例至少已经启动.可是数据库是否挂载,是否打开.不得而知 asm crs_stat -t updb.db online srvctl status database -d updb db sqlplus  -s / as sysdba select open_mode from database; 通过查询该视

HDU3351_Seinfeld【栈】

Seinfeld Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1381    Accepted Submission(s): 682 Problem Description I'm out of stories. For years I've been writing stories, some rather silly, just

Shell第二篇:正则表达式和文本处理工具

一 什么是正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 生活中处处都是正则:     比如我们描述:4条腿      你可能会想到的是四条腿的动物或者桌子,椅子等     继续描述:4条腿,活的           就只剩下四条腿的动物这一类了 在linux中,通配符是由shell解释的,而正则表达式则是由命令解释的,下面我们就为大家介绍三种文本处理工具/命令:grep.sed.awk,它们三者均可以解释正