844. 比較含退格的字串

hisun9發表於2024-11-11

題目

說實話自己在嘗試這道題的時候沒什麼清晰的思路和實現方法。

看了官方題解,官方提供了兩種方法:

方法一:

img

這個重構字串剛開始也想到了,但是不知道怎麼去實現,看了官方題解後,不禁一顫,噢,這是棧的運用啊,仔細想想,也覺得退格帶來的效果真的很像棧頂元素的彈出。

官方程式碼如下:

class Solution {
public:
    bool backspaceCompare(string S, string T) {
        return build(S) == build(T);
    }

    string build(string str) {
        string ret;
        for (char ch : str) {
            if (ch != '#') {
                ret.push_back(ch);
            } else if (!ret.empty()) {
                ret.pop_back();
            }
        }
        return ret;
    }
};

方法二:

img

官方程式碼如下:

class Solution {
public:
    bool backspaceCompare(string S, string T) {
        int i = S.length() - 1, j = T.length() - 1;
        int skipS = 0, skipT = 0;

        while (i >= 0 || j >= 0) {
            while (i >= 0) {
                if (S[i] == '#') {
                    skipS++, i--;
                } else if (skipS > 0) {
                    skipS--, i--;
                } else {
                    break;
                }
            }
            while (j >= 0) {
                if (T[j] == '#') {
                    skipT++, j--;
                } else if (skipT > 0) {
                    skipT--, j--;
                } else {
                    break;
                }
            }
            if (i >= 0 && j >= 0) {
                if (S[i] != T[j]) {
                    return false;
                }
            } else {
                if (i >= 0 || j >= 0) {
                    return false;
                }
            }
            i--, j--;
        }
        return true;
    }
};

然後照著官方方法二敲程式碼的時候又踩了一個坑

我是這樣寫的

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        int i = s.length() - 1, j = t.length() - 1;
        int skips = 0, skipt = 0;

        while (i >= 0 || j >= 0)
        {
            while (i >= 0)
            {
                if (s[i] == '#')
                    skips++, i--;
                else if(skips > 0)
                    skips--, i--;
                else
                    break;
            }

            while (j >= 0)
            {
                if (t[j] == '#')
                    skipt++, j--;
                else if (skipt > 0)
                    skipt--, j--;
                else 
                    break;
            }

            if (i >= 0 && j >= 0)
                if (s[i] != t[j])
                    return false;
            else
                if (i >= 0 || j >= 0)
                    return false;

            i--, j--;

        }
        return true;
    }
   
};

想著如果if或者else後面的語句只有一句就不用加大括號,簡便一點,但是好心辦壞事,不能ac,

原因就是if會自動和它最近的else語句自動組成if-else語句,才錯了。

附上用方法二分析例子圖片

img

img

其中這張圖片是若大wile寫成while (i >= 0 && j >= 0)的一個不透過的案例,因為一定要兩個字串都走到頭沒出問題才說明真的沒出問題,即要讓兩個字串都走完,如果用while (i >= 0 && j >= 0)的話,只要有一方走完了就退出大while了,就直接返回true了,並沒有判斷是否有一方還有剩餘元素。如果大while寫出while (i >= 0 || j >= 0)的話,會透過這個大while裡面的這段程式碼:

if (i >= 0 && j >= 0) {
    if (S[i] != T[j]) {
        return false;
    }
} else {
    if (i >= 0 || j >= 0) {
        return false;
    }
}

如果一方走完,一方還沒走完(即還有元素剩餘的話)就會進入else中的if語句,返回false。

相關文章