Backspace String Compare 比較含退格的字串
給定 S
和 T
兩個字串,當它們分別被輸入到空白的文字編輯器後,判斷二者是否相等,並返回結果。 #
代表退格字元。
示例 1:
輸入:S = "ab#c", T = "ad#c" 輸出:true 解釋:S 和 T 都會變成 “ac”。
示例 2:
輸入:S = "ab##", T = "c#d#" 輸出:true 解釋:S 和 T 都會變成 “”。
示例 3:
輸入:S = "a##c", T = "#a#c" 輸出:true 解釋:S 和 T 都會變成 “c”。
示例 4:
輸入:S = "a#c", T = "b" 輸出:false 解釋:S 會變成 “c”,但 T 仍然是 “b”。
提示:
1 <= S.length <= 200
1 <= T.length <= 200
S
和T
只含有小寫字母以及字元'#'
。
思路一:採用輔助棧的方法,這道題可以模擬鍵盤輸入帶退格鍵的操作,所以可以用棧來模擬這種操作,我們需要兩個輔助字串a和b分別對應字串S和T的最終結果,然後遍歷字串S,如果遇到的字元是'#'且a不為空,就彈出棧頂元素,如果不是'#'就壓入棧頂,這樣遍歷完S後最終a中的所有元素便是經過了退格鍵操作後的剩餘元素,同理我們對b也做相同的操作,最後比較a和b是否相等。
參考程式碼:(時間複雜度O(n),空間複雜度(O(S+T)))
class Solution { public: bool backspaceCompare(string S, string T) { string a = "", b = ""; for (auto c : S) { if (c == '#') a.size() > 0 ? a.pop_back() : void(); else a.push_back(c); } for (auto c : T) { if (c == '#') b.size() > 0 ? b.pop_back() : void(); else b.push_back(c); } return !a.compare(b); } };
思路二:由於題目的follow up希望我們能優化函式的時間複雜度到O(n),而空間複雜度為O(1),所以上述方法不能用。這裡我們這樣想,倒著遍歷字串S和T,如果遇到'#'就對其進行計數,記為count,因為count最終是要消去前面的count個非'#'字元的,所以我們的邏輯便是如果遇到的字元為'#'或者count>0,就不斷迴圈,如果再前面一個字元還是'#',就count++,否則就count--,當我們退出迴圈時便意味著count個'#'號和count個非'#'號相互消去了,同理對T也做同樣操作。當退出內層S和T的迴圈時,表示這時S和T中的最後一個字元一定不會被消去,然後進行比較是否相等,如果相等就S和T都向前移一個字元,否則就返回false。這裡要注意一點,由於在內層兩個迴圈下有可能會出現S或者T的下標小於0,如果有一個小於0,就意味著至少其中一個已經沒有了有效字元,而另一方一定還有有效字元,這時只要直接返回兩個的下標即可。(意味著兩個都沒有有效字元返回true,其他情況返回false)
參考程式碼:
class Solution {
public:
bool backspaceCompare(string S, string T) {
int m = S.size() - 1, n = T.size() - 1, countS = 0, countT = 0;
while (m >= 0 || n >= 0) {
while (m >= 0 && (S[m] == '#' || countS > 0)) {
S[m--] == '#' ? countS++ : countS--;
}
while (n >= 0 && (T[n] == '#' || countT > 0)) {
T[n--] == '#' ? countT++ : countT--;
}
if (m < 0 || n < 0) return m == n;
if (S[m] != T[n]) return false;
else {
m--; n--;
}
}
return m == n;
}
};