題目:請實現乙個函式,把字串中的每個空格替換成「%20」。
對於這個問題,初見,可能感覺會比較簡單,但隱藏了很多陷阱,需要考慮全面。
陷阱1:由乙個字元,替換為,三個字元,那麼字串肯定變長,需要考慮原字串記憶體是否足夠
陷阱2:空指標檢查,不能忘記
陷阱3:時間複雜度很關鍵
最直觀的做法(從前向後替換):從頭到尾掃面字串,每一次碰到空格字元的時候做替換。由於是把1個字元替換成3個字元,我們必須要把空格後面的所有字元都後移兩個位元組,否則就有兩個字元被覆蓋。
這樣做的話,對於乙個存在多個空格的字串,很明顯存在移動多次的字元。增加了時間複雜度。
這種做法**如下:
/** 一般解法,時間複雜度o(n^2) */
void replace_blank2(char str,int length)
old_len = i; // 原字串的長度
new_len = old_len + j*2; // 新字串的長度
if(new_len >= length) // 檢查記憶體是否足夠
return;
p1 = 0; // p1指向最開始
p2 = old_len; // p2指向結尾
while(str[p1] != '\0')
old_len = old_len + 2;
p2 = old_len; // p2再次指向最後
str[p1++] = '%'; // 空格替換
str[p1++] = '2';
str[p1++] = '0';}}
}
逆向思維做法:從後向前替換,先遍歷整個字串,得出空格總數,從而計算出替換後字串的總長度。這樣就知道了最後面的字元需要移動的總位數,就相當於將後面本來要移動多次的字元,一次性先移掉。然後從後向前替換空格。
這樣所有字元都只需移動一次,時間複雜度大大降低。
如下圖所示:
**如下:
/** 時間複雜度o(n) */
void replace_blank(char str,int length)
len_of_str = i;
num_of_blank = j;
new_len_of_str = len_of_str + num_of_blank*2;
if(new_len_of_str >= length)
return;
p2 = new_len_of_str;
p1 = len_of_str;
while(p1 >= 0 && p2 > p1)
else
//p1--;}}
主函式如下:(可以新增其他測試用例)
int main()
結果如下:
/*點滴積累,我的一小步o(∩_∩)o~*/
替換空格(劍指offer面試題4)
分析 從頭到尾掃瞄字串,遇到空格就替換,導致後面的字元都要向後移,意味著總時間複雜度為o n 2 更好的辦法,從字串後面遍歷替換。先遍歷所有的空格,每多乙個空格,字串長度加2個,也就是說最後替換後的字串長度為原長度 2 空格數,設定兩個指標,指向原始字串末尾和新字串末尾,依次向前遍歷,原始字串指標遇...
劍指offer 面試題4 替換空格
題目由來 在網路程式設計中,如果url引數中含有特殊字元,如空格 等,可能導致伺服器端無法獲得正常的引數值。我們需要將這些特殊符號轉換成伺服器可以識別的字元。轉換的規則是在 後面跟上ascii碼的兩位十六進製制的表示。比如空格的ascii碼是32,即十六進製制的0x20,因此空格被替代成 20 思路...
劍指offer 面試題4 替換空格
由於我在實現的時候使用的是c 的string,所以從後往前複製和從前往後複製,時間複雜度是一樣的。如果使用char 陣列實現,則從後往前複製更高效。重點是掌握這種反向思維。class solution 初始化新string string res s.size 2 countblank,a 必須將si...