[LeetCode] 844. Backspace String Compare 退格字符串比較


 

Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character.

Example 1:

Input: S = "ab#c", T = "ad#c" Output: true Explanation: Both S and T become "ac". 

Example 2:

Input: S = "ab##", T = "c#d#" Output: true Explanation: Both S and T become "". 

Example 3:

Input: S = "a##c", T = "#a#c" Output: true Explanation: Both S and T become "c". 

Example 4:

Input: S = "a#c", T = "b" Output: false Explanation: S becomes "c" while T becomes "b". 

Note:

  1. 1 <= S.length <= 200
  2. 1 <= T.length <= 200
  3. S and T only contain lowercase letters and '#' characters.

Follow up:

  • Can you solve it in O(N) time and O(1)space?

 

這道題給了我們兩個字符串,里面可能會有井號符#,這個表示退格符,鍵盤上的退格鍵我們應該都很熟悉吧,當字打錯了的時候,肯定要點退格鍵來刪除的。當然也可以連續點好幾下退格鍵,這樣就可以連續刪除了,在例子2和3中,也確實能看到連續的井號符。題目搞懂了之后,就開始解題吧,博主最先想的方法就是對S和T串分別處理完退格操作后再進行比較,那么就可以使用一個子函數來進行字符串的退格處理,在子函數中,我們新建一個結果 res 的空串,然后遍歷輸入字符串,當遇到退格符的時候,判斷若結果 res 不為空,則將最后一個字母去掉;若遇到的是字母,則直接加入結果 res 中即可。這樣S和T串同時處理完了之后,再進行比較即可,參見代碼如下:

 

解法一:

class Solution {
public:
    bool backspaceCompare(string S, string T) {
        return helper(S) == helper(T);      
    }
    string helper(string str) {
        string res = "";
        for (char c : str) {
            if (c == '#') {
                if (!res.empty()) res.pop_back();
            } else {
                res.push_back(c);
            }
        }
        return res;
    }
};

 

我們也可以不使用單獨的子函數,而是直接用 for 循環來處理S和T串,當然原理都是一樣的,分別建立s和t的空串,然后進行退格操作,最后比較s和t串是否相等即可,參見代碼如下:

 

解法二:

class Solution {
public:
    bool backspaceCompare(string S, string T) {
        string s = "", t = "";
        for (char c : S) c == '#' ? s.size() > 0 ? s.pop_back() : void() : s.push_back(c);
        for (char c : T) c == '#' ? t.size() > 0 ? t.pop_back() : void() : t.push_back(c);
        return s == t;
    }
};

 

這道題的 follow up 讓我們使用常數級的空間復雜度,就是說不能新建空的字符串來保存處理之后的結果,那么只能在遍歷的過程中同時進行比較,只能使用雙指針同時遍歷S和T串了。我們采用從后往前遍歷,因為退格是要刪除前面的字符,所以倒序遍歷要好一些。用變量i和j分別指向S和T串的最后一個字符的位置,然后還需要兩個變量 cnt1 和 cnt2 來分別記錄S和T串遍歷過程中連續出現的井號的個數,因為在連續井號后,要連續刪除前面的字母,如何知道當前的字母是否是需要刪除,就要知道當前還沒處理的退格符的個數。好,現在進行 while 循環,條件是i和j至少有一個要大於等於0,然后對S串進行另一個 while 循環,條件是當i大於等於0,且當前字符是井號,或者 cnt1 大於0,若當前字符是退格符,則 cnt1 自增1,否則 cnt1 自減1,然后i自減1,這樣就相當於跳過了當前的字符,不用進行比較。對T串也是做同樣的 while 循環處理。之后若i和j有一個小於0了,那么可以根據i和j是否相等的情況進行返回。否則再看若S和T串當前的字母不相等,則返回 false,因為當前位置的退格符已經處理完了,剩下的字母是需要比較相等的,若不相等就可以直接返回 false 了。最后當外層的 while 循環退出后,返回i和j是否相等,參見代碼如下:

 

解法三:

class Solution {
public:
    bool backspaceCompare(string S, string T) {
        int i = (int)S.size() - 1, j = (int)T.size() - 1, cnt1 = 0, cnt2 = 0;
        while (i >= 0 || j >= 0) {
            while (i >= 0 && (S[i] == '#' || cnt1 > 0)) S[i--] == '#' ? ++cnt1 : --cnt1;
            while (j >= 0 && (T[j] == '#' || cnt2 > 0)) T[j--] == '#' ? ++cnt2 : --cnt2;
            if (i < 0 || j < 0) return i == j;
            if (S[i--] != T[j--]) return false;
        }
        return i == j;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/844

 

參考資料:

https://leetcode.com/problems/backspace-string-compare/

https://leetcode.com/problems/backspace-string-compare/discuss/135603/C%2B%2BJavaPython-O(N)-time-and-O(1)-space

https://leetcode.com/problems/backspace-string-compare/discuss/135873/8-lines-C%2B%2B-O(1)-space-easy-to-understand

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM