1. 程式人生 > >Backspace String Compare 比較含退格的字串

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. 1 <= S.length <= 200
  2. 1 <= T.length <= 200
  3. 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;     
    }
};