844. 比较含退格的字符串 [简单][但是写不对]

 题目描述:


解题思路:

这里给出官方解法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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值