题目大意
给你两个带有‘#’字符的字符串s和t,其中‘#’代表一次退格操作,要求你比较s和t是否相同。
思路
第一个想法就是用栈处理退格操作,很简单就AC了,但是空间O(n),时间O(n),不是最优。另外一种思路是双指针,对于单个字符串s,可以抽象出一个函数proc来处理,函数proc负责处理退格操作,使字符串s变回常规不带退格操作的字符串,proc返回处理后的字符串的真实长度。具体的双指针思路如下:
定义两个指针l和r,其中r遍历整个字符串,l代表新字符串最后一个元素的下一个元素,也即新字符串的长度。最开始l = r = 0,随后分情况更新 l 和 r :
- 当r指向的字符是普通字母时,将r指向的字符赋值给l指向的位置,并且l和r都加一(即前进一步)。
- 当r指向的字符是井号字符时,代表遇到了退格操作,将l后退一步,r依旧前进一步。这里还需要判断l是否已经退到0,如果l已经退到0则不用再退。
r完整遍历完字符串以后即得到长度为 l 的不带退格操作的常规字符串,再进行比较即可。
代码:
class Solution {
public:
int proc(string& s){
int l = 0,r = 0;
int n = s.size();
while(r < n){
if(s[r] != '#')s[l++] = s[r++]; //r遇到正常字符
else if(s[r] == '#'){ //r遇到退格
if(l != 0)--l; //l若没有退到0,则后退一步
++r;
}
}
return l; //返回处理后字符串的长度
}
bool backspaceCompare(string s, string t) {
if(s.size() == 1 && t.size() == 1)
return s[0] == t[0];
int sn = proc(s); //sn即为s字符串处理后的长度
int st = proc(t); //st为t字符串处理后的长度
if(sn != st)return false; //处理后s和t的长度不等则两字符串一定不相同
for(int i = 0;i < sn; ++i){ //若处理后的字符串还存在不同的字符,则s和t不相同
if(s[i] != t[i])return false;
}
return true;
}
};