1. 程式人生 > >【LeetCode題解】844_比較含退格的字串(Backspace-String-Compare)

【LeetCode題解】844_比較含退格的字串(Backspace-String-Compare)

目錄

更多 LeetCode 題解筆記可以訪問我的 github

描述

給定 ST 兩個字串,當它們分別被輸入到空白的文字編輯器後,判斷二者是否相等,並返回結果。 # 代表退格字元。

示例 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. ST 只含有小寫字母以及字元 '#'

解法一:字串比較

思路

當拿到這道題時,可能最直接的想法就是將兩個字串所對應的結果進行比較

。為了能夠得到字串所對應的結果,需要藉助棧來模擬鍵入的過程。從左往右遍歷字串,如果當前的字元並不是退格字元 #,那麼就將當前的字元壓入棧中;如果當前的字元是退格字元且棧不為空,那麼就將棧頂的元素彈出。最後,棧中剩餘字元所組成的字串即為所求。

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\) 分別表示字串 ST 的長度。
  • 空間複雜度:\(O(m + n)\)

解法二:雙指標(推薦)

思路

第二種解法本質上也是對字串所對應的結果進行比較,只不過與解法一不同的是,解法二是逐個字元進行比較,當發現有字元不相等時,返回 false。為了能對兩個字串所對應的結果進行比較,需要兩個指標,用於指向比較的字元。與此同時,當遇到退格符 # 時,跳過下一個非退格符的符號,取下下個字元進行比較。為了能夠更加生動地說明這個過程,採用了示例1的兩個字元作為函式的輸入(S="ab#c"T="ad#c"),用於演示整個過程,具體的過程見下面的一系列圖片。

  • 初始時, i=3j=3,此時由於兩個索引所對應的字元並不是退格符,直接進行比較(結果相等,ij 都減一進入下一次迴圈)

在這裡插入圖片描述

  • i=2j=2 時,此時兩個索引所對應的字元都是退格符,因此跳過下一個非退格符的字元(字串 S 中是字元 b,而字串 T 中是字元 d

在這裡插入圖片描述

  • i=0j=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\) 分別表示字串 ST 的長度。
  • 空間複雜度:\(O(1)\)