題目
說實話自己在嘗試這道題的時候沒什麼清晰的思路和實現方法。
看了官方題解,官方提供了兩種方法:
方法一:
這個重構字串剛開始也想到了,但是不知道怎麼去實現,看了官方題解後,不禁一顫,噢,這是棧的運用啊,仔細想想,也覺得退格帶來的效果真的很像棧頂元素的彈出。
官方程式碼如下:
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;
}
};
方法二:
官方程式碼如下:
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語句,才錯了。
附上用方法二分析例子圖片
其中這張圖片是若大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。