给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,请你判断二者是否相等。# 代表退格字符。
如果相等,返回 true ;否则,返回 false 。
注意:如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:s = "ab#c", t = "ad#c"
输出:true
解释:S 和 T 都会变成 “ac”。
示例 2:
输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 “”。
示例 3:
输入:s = "a##c", t = "#a#c"
输出:true
解释:s 和 t 都会变成 “c”。
示例 4:
输入:s = "a#c", t = "b"
输出:false
解释:s 会变成 “c”,但 t 仍然是 “b”。
栈方法
最容易想到的方法是将给定的字符串中的退格符和应当被删除的字符都去除,还原给定字符串的一般形式。然后直接比较两字符串是否相等即可。
具体地,我们用栈处理遍历过程,每次我们遍历到一个字符:
-
如果它是退格符,那么我们将栈顶弹出;
-
如果它是普通字符,那么我们将其压入栈中。
var backspaceCompare = function (s, t) { return backs(s) == backs(t) function backs (str) { let stack = [] for (let i = 0; i < str.length; i++) { if (str[i] == "#") { if (stack.length != 0) { stack.pop() } } else { stack.push(str[i]) } } return stack.join('') } }
双指针
一个字符是否会被删掉,只取决于该字符后面的退格符,而与该字符前面的退格符无关。因此当我们逆序地遍历字符串,就可以立即确定当前字符是否会被删掉。
具体地,我们定义 skip 表示当前待删除的字符的数量。每次我们遍历到一个字符:
- 若该字符为退格符,则我们需要多删除一个普通字符,我们让 skip 加 1;
- 若该字符为普通字符:
- 若 skip 为 0,则说明当前字符不需要删去;
- 若 skip 不为 0,则说明当前字符需要删去,我们让 skip 减 1。
这样,我们定义两个指针,分别指向两字符串的末尾。每次我们让两指针逆序地遍历两字符串,直到两字符串能够各自确定一个字符,然后将这两个字符进行比较。重复这一过程直到找到的两个字符不相等,或遍历完字符串为止。
var backspaceCompare = function (s, t) {
let i = s.length - 1,
j = t.length - 1,
skipS = 0,
skipT = 0;
while (i >= 0 || j >= 0) {
while (i >= 0) {
if (s[i] === '#') {
skipS++;
i--;
} else if (skipS > 0) {
skipS--;
i--;
} else break;
}
while (j >= 0) {
if (t[j] === '#') {
skipT++;
j--;
} else if (skipT > 0) {
skipT--;
j--;
} else break;
}
if (s[i] !== t[j]) return false;
i--;
j--;
}
return true;
};