【LeetCode題解】844_比較含退格的字串(Backspace-String-Compare)
目錄
更多 LeetCode 題解筆記可以訪問我的 ofollow,noindex" target="_blank">github 。
描述
給定 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
只含有小寫字母以及字元'#'
。
解法一:字串比較
思路
當拿到這道題時,可能最直接的想法就是 將兩個字串所對應的結果進行比較 。為了能夠得到字串所對應的結果,需要藉助棧來模擬鍵入的過程。從左往右遍歷字串,如果當前的字元並不是退格字元 #
,那麼就將當前的字元壓入棧中;如果當前的字元是退格字元且棧不為空,那麼就將棧頂的元素彈出。最後,棧中剩餘字元所組成的字串即為所求。
Java 實現
class Solution { public boolean backspaceCompare(String S, String T) { return build(S).compare(build(T)); } private String build(String s) { Stack<Character> stack = new Stack<>(); for (char c : s.toCharArray()) { if (c != '#') { stack.push(c); } else if (!stack.isEmpty()) { stack.pop(); } } return String.valueOf(stack); } }
Python 實現
class Solution: def backspaceCompare(self, S, T): """ :type S: str :type T: str :rtype: bool """ def build(s): stack = [] for c in s: if c != '#': stack.append(c) elif stack: stack.pop() return ''.join(stack) return build(S) == build(T)
複雜度分析
- 時間複雜度: \(O(m + n)\) ,其中 \(m\) 和 \(n\) 分別表示字串
S
和T
的長度。 - 空間複雜度: \(O(m + n)\)
解法二:雙指標(推薦)
思路
第二種解法本質上也是對字串所對應的結果進行比較,只不過與解法一不同的是, 解法二是逐個字元進行比較 ,當發現有字元不相等時,返回 false
。為了能對兩個字串所對應的結果進行比較,需要兩個指標,用於指向比較的字元。與此同時,當遇到退格符 #
時,跳過下一個非退格符的符號,取下下個字元進行比較。為了能夠更加生動地說明這個過程,採用了示例1的兩個字元作為函式的輸入( S="ab#c"
、 T="ad#c"
),用於演示整個過程,具體的過程見下面的一系列圖片。
- 初始時,
i=3
、j=3
,此時由於兩個索引所對應的字元並不是退格符,直接進行比較(結果相等,i
和j
都減一進入下一次迴圈)
- 當
i=2
、j=2
時,此時兩個索引所對應的字元都是退格符,因此跳過下一個非退格符的字元(字串S
中是字元b
,而字串T
中是字元d
)
- 當
i=0
、j=0
時,此時兩個索引所對應的字元都不是退格符,再一次進行比較,結果相等,至此迴圈結束,最終函式返回結果為true
Java 實現
class Solution { public boolean backspaceCompare(String S, String T) { int i = S.length() - 1, j = T.length() - 1; int sSkip = 0, tSkip = 0; while (i >= 0 || j >= 0) { // 找到字串S所對應的結果的下一個字元 while (i >= 0) { if (S.charAt(i) == '#') { --i; ++sSkip; } else if (sSkip > 0) { --i; --sSkip; } else { break; } } // 找到字串T所對應的結果的下一個字元 while (j >= 0) { if (T.charAt(j) == '#') { --j; ++tSkip; } else if (tSkip > 0) { --j; --tSkip; } else { break; } } // 如果索引i和j所對應的字元不相等,返回false if (i >= 0 && j >= 0 && S.charAt(i) != T.charAt(j)) { return false; } // 如果遍歷完一個字串的同時,另一個字串還未遍歷完,返回false if ((i >= 0) != (j >= 0)) { return false; } --i; --j; } return true; } }
Python 實現
class Solution: def backspaceCompare(self, S, T): """ :type S: str :type T: str :rtype: bool """ i, j, s_skip, t_skip = len(S) - 1, len(T) - 1, 0, 0 while i >= 0 or j >= 0: # 找到字串S所對應結果的下一個字元 while i >= 0: if S[i] == '#': i -= 1 s_skip += 1 elif s_skip > 0: i -= 1 s_skip -= 1 else: break # 找到字串T所對應結果的下一個字元 while j >= 0: if T[j] == '#': j -= 1 t_skip += 1 elif t_skip > 0: j -= 1 t_skip -= 1 else: break # 如果索引i和j所對應的字元不相等,返回False if i >= 0 and j >= 0 and S[i] != T[j]: return False # 如果遍歷完一個字元的同時,另一個字元還未遍歷完,返回False if (i >= 0) != (j >= 0): return False return True # Time Limit Exceeded
複雜度分析
- 時間複雜度: \(O(m + n)\) ,其中 \(m\) 和 \(n\) 分別表示字串
S
和T
的長度。 - 空間複雜度: \(O(1)\)