題目描述
請實現一個函數,將一個字符串中的每個空格替換成“%20”。例如,當字符串爲We Are Happy.則經過替換之後的字符串爲We%20Are%20Happy。
當看到這個題時,我的第一個反應就是創建一個新的數組,大小剛好是原來數組的長度加上空格數*3。
- 先創建新數組
- 然後將字符串一個字符一個字符拷貝
- 當遇到空格則添加爲%20,然後繼續拷貝
- 重複以上過程,直到字符串結束
但是,如果題目不讓你創建新的空間怎麼辦?
你可能會說,沒事,我還有一種方法,就是從頭到尾遍歷一遍。
- 從頭到尾遍歷一遍
- 當遇到空格,我就把後邊的字符都統統往後挪兩個
- 然後將空格處替換成%20
- 重複以上步驟
這樣也是沒有創建新的空間,但是這樣的時間複雜度是O(n^2)
接下來我來說一個時間複雜度爲O(n)的方法,但是前提是原來的空間要足夠。
- 我們可以先遍歷一次字符串,這樣就可以統計出字符串空格的總數,並可以由此計算出替換之後的字符串的總長度。
- 我們從字符串的尾部開始複製和替換。
- 首先準備兩個指針,P1和P2,P1指向原始字符串的末尾,而P2指向替換之後的字符串的末尾。
- 然後我們向前移動指針P1,逐個把它指向的字符複製到P2指向的位置,直到碰到第一個空格爲止。
- 碰到第一個空格之後,把P1向前移動1格,在P2之前插入字符串"%20"。由於"%20"的長度爲3,同時也要把P2向前移動3格。
- 重複上述步驟
接下來,就用代碼來實現一下:
class Solution {
public:
void replaceSpace(char *str,int length) {
if(str == NULL && length <= 0){
return;
}
/*rellen爲字符串str的實際長度*/
int rellen = 0; //原始長度
int blank = 0; //空格數
int i;
while(str[i++] != '\0'){ //遍歷字符串
++rellen; //長度+1
if(str[i] == ' '){
++blank; //遇到空格+1
}
}
/*new_length爲把空格替換成'%20'之後的長度*/
int newlen = rellen + 2 * blank;
int index_old = rellen; //原始字符串末尾索引值
int index_new = newlen; //計算長度後的字符串末尾索引值
/*index_old指針開始向前移動,如果遇到空格,替換成'%20',否則進行復制操作*/
while(index_old >= 0 && index_new > index_old){
if(str[index_old] == ' '){
str[index_new--] = '0';
str[index_new--] = '2';
str[index_new--] = '%';
}
else{
str[index_new--] = str[index_old];
}
--index_old;
}
}
};