题目描述:
解题思路:
这里给出官方解法1.2 以及 由传统双指针法自己写的3.
解法1:使用两个栈来存储每个字符串的元素。
- 步骤1:当我们遍历到一个字符时,我们直接把它压入栈中;
- 步骤2:当我们遍历到'#'字符时,我们需要判断栈是否为空,如果为空则直接忽略掉该退格字符,否则弹出栈顶字符元素
- 返回结果:我们遍历完两个字符串后,只需要比对两个栈剩下的元素是否相等,即可决定返回 true 还是 false。 时间复杂度是 O(m+n),空间复杂度是 O(m+n)
char* build(char* str) {
int n = strlen(str), len = 0;
char* ret = malloc(sizeof(char) * (n + 1));
for (int i = 0; i < n; i++) {
if (str[i] != '#') {
ret[len++] = str[i];
} else if (len > 0) {
len--;
}
}
ret[len] = '\0';
return ret;
}
bool backspaceCompare(char* S, char* T) {
return strcmp(build(S), build(T)) == 0;
}
解法2:双指针法。
我们可以维护两个计数器,记录下退格的个数,然后倒序遍历字符串来决定当前字符是否需要跳过
- 步骤1:维护两个计数器 skipS 和 skipT,然后开始倒序遍历字符串
- 步骤2:当我们遇到‘#’时,将对应的计数器 + 1;当我们遇到字符时,会有如下的判断:
- 如果退格计数器 = 0,那么该字符无法跳过,此时应该比对当前的字符是否相同
- 如果退格计数器 > 0,那么该字符需要跳过,所以需要让遍历指针-1,同时让计数器-1
- 步骤3:如果遍历过程中,发现两个位置上的字符并不相同,或者有其中一个字符串已经遍历完,那么直接返回 false,否则继续往前遍历剩下的字符
- 最后如果两个字符串都已经遍历完,那么证明它们经过退格的操作后是相等的字符串,返回 true;时间复杂度是 O(m+n),空间复杂度是O(1)
bool backspaceCompare(char * s, char * t){
int i = strlen(s)-1,j = strlen(t) - 1;//i指向s,j指向t,从右往左
int skipS = 0,skipT = 0;//初始#数量为0
while(i>=0||j>=0){//用||表示,只要有一方没遍历完,就参与循环体内的判断。如果能遍历完,return true,不能遍历完,return false
while(i>=0){//考虑s
if('#'==s[i]){//遇到#
skipS++;
i--;
}else if(skipS>0){//遇到字母,有未使用的#
skipS--;
i--;
}else{//遇到字母,#用完了
break;
}
}
while(j>=0){//考虑t
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{//至少有一方遍历完毕(i<0||j<0)
if(i>=0||j>=0){//有一方没有遍历完毕。()
return false;
}
//如果双方都遍历完毕,下一次循环,就跳出了。return true
}
i--,j--;
}
return true;//双方均遍历完毕
}
解法3:双指针法,遍历完两个字符串,最后比较。
- 步骤1:设置slow fast双指针,然后开始使用for循环正序遍历字符串
- 步骤2:
- 当fast指针指向的字符不是‘#’时,将slow指向的位置改为当前fast指向的字符,slow向后移一位。
- 当fast指针指向的字符是‘#’时,将slow指向的位置向前移一位,这样一来fast继续向后遍历时,遇到非#字母,会将该字母覆盖掉slow指向的字母,借此完成#的退格操作。
- 最后比较两个字符串是否相等即可。时间复杂度是 O(m+n),空间复杂度是O(1)
char* build(char* str) {
int n = strlen(str);
int slow=0,fast=0; //设置双指针
for(fast;fast<n;fast++){
if(str[fast] != '#'){ //fast指向不为#时,当前fast指向的字母先保留
str[slow++]=str[fast];
}
else if(slow>0){slow--;} //为#时,slow后退一步,接下来如果fast读入字母,会将slow指向的位置字母替换掉,以此完成#的退格操作
}
str[slow] = '\0';
return str;
}
bool backspaceCompare(char* S, char* T) {
return strcmp(build(S), build(T)) == 0;
}