解题思路:
思路一: 模拟使用栈,当将要入栈的字符是“#”时,栈顶元素出栈(删除字符串中的元素)。最后。比较两个字符串是否相同。这种解法并不是最优解,它的空间复杂度为:n + m
(如果题目要求 原地退格,思路一便不再适用。)
我们便引入 快慢指针思想。
快慢指针(双指针):通过一个快指针和慢指针在一个for循环下完成两个for循环工作。
思路二:
由于 # 号只会消除左边的一个字符,所以对右边的字符无影响,所以我们选择从后往前遍历 s,t 字符串。
1.准备两个指针Si,Ti分别指向字符串s,t 的末位字符,再准备两个变量counts,countt 分别记录 字符串s,t 中 “#” 的数量。
2.从后往前遍历字符串,所遇到的情况有三种,如下:
2.1 若当前字符是 #,则 counts(countt)加1,Si(Ti)减1(继续判断下一个字符);
2.2 若当前字符不是 #,且 counts(countt) 不为 0,则 counts(countt)减 1,Si(Ti)减1(继续判断下一个字符,相当于此字符属于退格字符,不参与比较);
2.3 若当前字符不是 #,且 counts(countt)为 0,则代表当前字符不会被消除,我们可以用来和 s(t) 中的当前字符作比较。
若对比过程出现 s, t 当前字符不匹配,则遍历结束,返回 false,若 s,t 都遍历结束,且都能一一匹配,则返回 true。
实现代码如下:
public boolean backspaceCompare(String s, String t) {
//s.length() 返回字符串的长度
int Si = s.length() - 1;
int Ti = t.length() - 1;
int counts = 0;
int countt = 0;
while(Si>=0 || Ti>=0){
while(Si >= 0){
if(s.charAt(Si) == '#'){
counts++;
Si--;
}else if(counts > 0){
counts--;
Si--;
}else{
break;
}
}
while(Ti >= 0){
if(t.charAt(Ti) == '#'){
countt++;
Ti--;
}else if(countt > 0){
countt--;
Ti--;
}else{
break;
}
}
if(Si >= 0 && Ti >= 0){
if(s.charAt(Si) != t.charAt(Ti)){
return false;
}
}else{
if(Si >=0 || Ti >= 0){
return false;
}
}
Si--;
Ti--;
}
return true;
}
易错、障碍点
1.java中的charAt()方法的使用:
java.lang.String.charAt() 方法:返回指定索引处的char值。索引范围是从0到length() - 1。
方法声明如下:
public char charAt(int index)
事例:
public class Test {
public static void main(String[] args) {
String s ="abc";
System.out.println(s.charAt(1));
}
}
输出结果为:b
算法看似简单,但实现起来还是会出现各种问题,尤其在判断返回时。纸上得来终觉浅,绝知此事要躬行 呀!