给定 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
只含有小写字母以及字符'#'
。
思路一:采用辅助栈的方法,这道题可以模拟键盘输入带退格键的操作,所以可以用栈来模拟这种操作,我们需要两个辅助字符串a和b分别对应字符串S和T的最终结果,然后遍历字符串S,如果遇到的字符是'#'且a不为空,就弹出栈顶元素,如果不是'#'就压入栈顶,这样遍历完S后最终a中的所有元素便是经过了退格键操作后的剩余元素,同理我们对b也做相同的操作,最后比较a和b是否相等。
参考代码:(时间复杂度O(n),空间复杂度(O(S+T)))
class Solution {
public:
bool backspaceCompare(string S, string T) {
string a = "", b = "";
for (auto c : S) {
if (c == '#') a.size() > 0 ? a.pop_back() : void();
else a.push_back(c);
}
for (auto c : T) {
if (c == '#') b.size() > 0 ? b.pop_back() : void();
else b.push_back(c);
}
return !a.compare(b);
}
};
思路二:由于题目的follow up希望我们能优化函数的时间复杂度到O(n),而空间复杂度为O(1),所以上述方法不能用。这里我们这样想,倒着遍历字符串S和T,如果遇到'#'就对其进行计数,记为count,因为count最终是要消去前面的count个非'#'字符的,所以我们的逻辑便是如果遇到的字符为'#'或者count>0,就不断循环,如果再前面一个字符还是'#',就count++,否则就count--,当我们退出循环时便意味着count个'#'号和count个非'#'号相互消去了,同理对T也做同样操作。当退出内层S和T的循环时,表示这时S和T中的最后一个字符一定不会被消去,然后进行比较是否相等,如果相等就S和T都向前移一个字符,否则就返回false。这里要注意一点,由于在内层两个循环下有可能会出现S或者T的下标小于0,如果有一个小于0,就意味着至少其中一个已经没有了有效字符,而另一方一定还有有效字符,这时只要直接返回两个的下标即可。(意味着两个都没有有效字符返回true,其他情况返回false)
参考代码:
class Solution {
public:
bool backspaceCompare(string S, string T) {
int m = S.size() - 1, n = T.size() - 1, countS = 0, countT = 0;
while (m >= 0 || n >= 0) {
while (m >= 0 && (S[m] == '#' || countS > 0)) {
S[m--] == '#' ? countS++ : countS--;
}
while (n >= 0 && (T[n] == '#' || countT > 0)) {
T[n--] == '#' ? countT++ : countT--;
}
if (m < 0 || n < 0) return m == n;
if (S[m] != T[n]) return false;
else {
m--; n--;
}
}
return m == n;
}
};