我們都遇到過的 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),從而提高了效率。

  以此類推,如果我們遇到的的算法題,從前往后遍歷需要多次重復復制移動元素,那么久可以考慮一下,是否可以從后往前遍歷,減少復制移動的次數,從而提高效率。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com