「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。
说在前面
很多人总是对前端开发存在一定的误解,甚至认为前端开发只是一个“切图仔”,但在我看来却并不是如此,现在是大前端时代,前端的很多技术迅速发展,给我们前端开发工程师带来很多新的技术路线,同时也给我们带来了许多新的挑战。为了更好地提升自身的技术水平和基础素养,我觉得前端工程师也非常有必要着力于提升自己的算法能力和逻辑思维,因此我自己在平时空余时间也会去寻找一些比较有意思的算法进行学习,目前仍在继续提升的阶段。
今日算法
题目链接
题目的链接为:leetcode-cn.com/problems/ba…
题目描述
给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。
示例
示例1
输入: s = "ab#c", t = "ad#c"
输出: true
解释: s 和 t 都会变成 "ac"。
示例2
输入: s = "ab##", t = "c#d#"
输出: true
解释: s 和 t 都会变成 ""。
提示
1 <= s.length, t.length <= 200s和t只含有小写字母以及字符'#'
解题思路
读完题目后我们可以知道,题意就是要我们判断将字符串中的退格操作执行后,两个修改后的字符串是否会相同,看到这里我们应该要想到可以使用栈来进行处理,让我们先来了解一下什么是栈。
栈
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。简单来说就是栈中元素出入栈顺序为后进先出。
栈题解
思路
使用两个栈来保存两个字符串的数据,遍历两个字符串,遇到退格(#)时栈顶元素出栈,遍历整个字符串之后我们便可以得出进行退格操作后的字符串,最后比较两个栈的元素即可。
代码
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var backspaceCompare = function(s, t) {
if(s === t) return true;
let sArr = [],tArr = [];
for(let i = 0; i < s.length; i++){
if(s[i] === '#') sArr.pop();
else{
sArr.push(s[i]);
}
}
for(let i = 0; i < t.length; i++){
if(t[i] === '#') tArr.pop();
else{
tArr.push(t[i]);
}
}
return tArr.join('') == sArr.join('');
};
进阶
- 你可以用
O(n)的时间复杂度和O(1)的空间复杂度解决该问题吗? 使用栈来处理这个问题时,我们会消耗很多的空间来进行数据保存,那么,我们可以不用栈来进行解题吗? 答案是可以的,我们可以使用双指针方法来进行解题,具体解题思路如下:
双指针
我们可以从后往前遍历,遇到一个'#'则说明前面需要忽略一个字符,我们则需要比较每一个不为'#'的字符是否相同即可。
代码
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var backspaceCompare = function(S, T) {
let i = S.length - 1,
j = T.length - 1,
skipS = 0,
skipT = 0;
// 大循环
while(i >= 0 || j >= 0){
// S 循环
while(i >= 0){
if(S[i] === '#'){
skipS++;
i--;
}else if(skipS > 0){
skipS--;
i--;
}else break;
}
// T 循环
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;
};