LeetCode - 844. 比较含退格的字符串
题目
844. 比较含退格的字符串 - 力扣(LeetCode)
思路
这道题是比较含退格的字符串,我看到题目后的第一反应是需要先处理退格符号,然后再比较两个字符串是否相等。
我的思路是:
- 分别处理两个字符串,将它们转换成删除了退格符号后的实际文本
- 然后比较这两个处理后的字符串是否相等
对于处理退格符号,我想到了两种方法:
第一种是使用栈。遍历字符串,遇到普通字符就入栈,遇到'#'就弹出栈顶元素(如果栈不为空)。最后栈中剩下的字符就是最终的字符串。这种方法时间和空间复杂度都是O(n)。
第二种是直接在字符串上操作。维护一个指针表示当前有效字符串的结束位置,遍历原字符串,遇到普通字符就将其放到指针位置并将指针后移,遇到'#'就将指针前移(如果可能的话)。最后指针前的子串就是最终的字符串。这种方法的空间复杂度可以优化到O(1)。
举个例子,对于示例1中的s = "ab#c":
- 遍历到'a',加入结果,结果变成"a"
- 遍历到'b',加入结果,结果变成"ab"
- 遍历到'#',删除上一个字符,结果变成"a"
- 遍历到'c',加入结果,结果变成"ac"
同样处理t = "ad#c":
- 最终结果也是"ac"
所以两个字符串相等,返回true。
在实际中,我会先实现第一种栈的方法,因为它更直观。如果要求优化空间复杂度,我再提出第二种方法。
还有一种更高级的解法是使用双指针从后向前遍历两个字符串,这样可以同时实现O(n)的时间复杂度和O(1)的空间复杂度。
读者可能出现的错误写法
class Solution {
public:bool backspaceCompare(string s, string t) {string one = result(s);string two = result(t);return s==t;}string result(string str){string st;for(int i =0;i<str.size();i++){if(st.empty() || str[i]!='#'){st.push_back(str[i]);}else{st.pop_back();}}return st;}
};
第一个错误是在backspaceCompare函数中,你在比较时使用了原始的字符串s和t,而不是处理后的字符串one和two。应该改为:return one == two;
第二个错误是在result函数中,当遇到'#'字符时的逻辑有问题。当前的代码是:
if(st.empty() || str[i]!='#')
{st.push_back(str[i]);
}
else
{st.pop_back();
}
这个逻辑会导致:
- 如果st为空或当前字符不是'#',就将当前字符加入结果
- 否则,弹出结果中的最后一个字符
问题在于,当st为空时,即使当前字符是'#',也会将'#'加入结果,这是不正确的。退格符应该删除前一个字符,如果没有前一个字符,就忽略这个退格符。
正确写法
class Solution {
public:bool backspaceCompare(string s, string t) {string one = result(s);string two = result(t);return one==two;}string result(string str){string st;for(int i =0;i<str.size();i++){if(str[i]!='#'){st.push_back(str[i]);}else if(!st.empty()){st.pop_back();}}return st;}
};