给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:S = "ab#c", T = "ad#c"
输出:true
解释:S 和 T 都会变成 “ac”。
方法1
利用 栈 ,正常字符直接入栈,遇到‘#’就删除栈内的一个字符;用StringBuilder
模拟栈[底层是char数组],单线程StringBuilder比StringBuffer效率高
class Solution {
public boolean backspaceCompare(String S, String T) {
return build(S).equals(build(T));
}
public String build(String str){
//StringBuilder模拟栈[底层是char数组],单线程StringBuilder比StringBuffer效率高
StringBuilder builder = new StringBuilder();
int length = str.length();
for(int i = 0; i < length; ++i){
char c = str.charAt(i);
//正常字符直接入栈
if(c != '#'){
builder.append(c);
}
//遇到‘#’需要删除栈内的一个字符
else if(builder.length() > 0){
builder.deleteCharAt(builder.length() - 1);
}
}
return builder.toString();
}
}
方法 2
双指针!双指针!
逆序从后往前,用delete计数未用的#个数,也就是需要删除的字符的个数,遇到#就++delete,遇到字符就判断,如果delete>0,那么–delete,消耗掉一个,如果delete=0,就说明当前字符需要保留,然后转向分析另外一个字符串,直到也遇到需要保留的字符,或者到了最头上;如果两个字符串当前字符相等,就继续向前,不相等或者其中有一个到了最头上就退出
class Solution {
public boolean backspaceCompare(String S, String T) {
//两个指针,从尾部开始
int sp = S.length() - 1, tp = T.length() - 1;
//当前未消耗的#个数
int delS = 0, delT = 0;
while(sp >= 0 || tp >= 0){
while(sp >= 0){
char c = S.charAt(sp);
//遇到#:未消耗的#加一
if(c == '#'){
++delS;
--sp;
}
//遇到正常字符:消耗#
else{
if(delS > 0){
--delS;
--sp;
}
//没有可以消耗的#:字符需要保留
else{
break;
}
}
}
while(tp >= 0){
char c = T.charAt(tp);
//遇到#:未消耗的#加一
if(c == '#'){
++delT;
--tp;
}
//遇到正常字符:消耗#
else{
if(delT > 0){
--delT;
--tp;
}
//没有可以消耗的#:字符需要保留
else{
break;
}
}
}
//两个字符串都没到头:比较留下的两个字符
if((sp >= 0) && (tp >= 0)){
//当前字符不相同或者其中有一个到头了就返回false;反之当前字符相等或者两个都到头了,就继续判断
if(S.charAt(sp) != T.charAt(tp)){
return false;
}
}
else if((sp >= 0) || (tp >= 0)){
return false;
}
//注意写法,这里不能加else,加了的话就只是两个都到头了这一种情况了,那么两个头没到头切字符相同的大括号里应该也加上下面两句
--sp;
--tp;
}
return true;
}
}
方法3
评论区看到的,如果可以修改源字符串的话,就可以有下面的写法,然而,java String是不可变的…只能用StringBuilder或者StringBuffer,那就又有额外空间了…
下面的代码不可用,当成伪代码
看就好了
class Solution {
public boolean backspaceCompare(String S, String T) {
int len1 = build(S);
int len2 = build(T);
return (len1 == len2) && (S.substring(0,len1).equals(T.substring(0,len2)));
}
public int build(String str){
int count = 0;
for(int i = 0; i < str.length(); ++i){
char c = str.charAt(i);
if(c != '#'){
str.charAt(count) = c;
count++;
}
else if(count > 0){
count--;
}
}
return count;
}
}