思路一;从后往前用双指针法(这个思路比较重要,但是难想到)
同时从后向前遍历S和T(i初始为S末尾,j初始为T末尾),记录#的数量,模拟消除的操作,如果#用完了,就开始比较S[i]和S[j]。
如果S[i]和S[j]不相同返回false,如果有一个指针(i或者j)先走到的字符串头部位置,也返回false。
class Solution {
public boolean backspaceCompare(String S, String T) {
int S_Len = S.length(), T_Len = T.length();
char[] S_arr = S.toCharArray(), T_arr = T.toCharArray();
int skipS = 0, skipT = 0;
for (int i = S_Len - 1, j = T_Len - 1; i >= 0 || j >= 0; i--, j--) {
while (i >= 0) {
if (S_arr[i] == '#') {
skipS++;
i--;
} else if (skipS > 0) {
// 遇到字符, 但由于需要回退, 所以还需要前移1位
skipS--;
i--;
} else {
// 遇到字符, 且不能回退了, 所以需要比对这个字符是否与T对应位置上的字符相等
break;
}
}
while (j >= 0) {
if (T_arr[j] == '#') {
skipT++;
j--;
} else if (skipT > 0) {
skipT--;
j--;
} else {
break;
}
}
if (i >= 0 && j >= 0) {
//处理过后如果从后往前一个个字母对比,如果不相同就返回false
if (S_arr[i] != T_arr[j]) return false;
} else if (i >= 0 || j >= 0) {
// 有其中一方已经遍历完整个字符串, 但另外一方没有遍历完整个字符串, 直接返回false
return false;
}
}
return true;
}
}
时间复杂度:O(n + m)
空间复杂度:O(1)
思路二:用栈来辅助遍历
// 普通方法(使用栈的思路)
class Solution {
public boolean backspaceCompare(String s, String t) {
StringBuilder ssb = new StringBuilder(); // 模拟栈
StringBuilder tsb = new StringBuilder(); // 模拟栈
// 分别处理两个 String
for (char c : s.toCharArray()) {
if (c != '#') {
ssb.append(c); // 模拟入栈
} else if (ssb.length() > 0){ // 栈非空才能弹栈
ssb.deleteCharAt(ssb.length() - 1); // 模拟弹栈
}
}
for (char c : t.toCharArray()) {
if (c != '#') {
tsb.append(c); // 模拟入栈
} else if (tsb.length() > 0){ // 栈非空才能弹栈
tsb.deleteCharAt(tsb.length() - 1); // 模拟弹栈
}
}
//比较栈剩下的值是否相同
return ssb.toString().equals(tsb.toString());
}
}
时间复杂度:O(n + m)
空间复杂度:O(n + m)
本文章只做笔记用途,谢谢观看!
参考:代码随想录