递归与栈刷题(二)

170 阅读1分钟

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

之前写了递归与栈刷题, 有兴趣的童鞋可以冲,接下来再刷两道递归与栈的题~~

一、入栈出栈

844. 比较含退格的字符串

给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

示例 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”。   提示:

  • 1 <= S.length <= 200

  • 1 <= T.length <= 200

  • S 和 T 只含有小写字母以及字符 '#'。

进阶:

你可以用 O(N) 的时间复杂度和 O(1) 的空间复杂度解决该问题吗?

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ba… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

设置两个栈,当遇到#则出栈,其他字符入栈;

当两个字符串都入栈后,比较两个栈的长度是否相等,若不相等,则两个字符串不可能相等,返回false;

遍历两个栈,比较两个栈的栈顶,如果栈顶不相等,则两个字符串不可能相等,返回false;直到栈为空时,战斗都相等则返回true。

代码实现

// 实现一个栈
class Stack {
    constructor() {
        this.stack = []
    }
    push(x) {
        this.stack.push(x);
    }
    pop() {
        if(this.empty()) return; 
        let top = this.top();
        this.stack.pop()
        return top;
    }
    top() {
        return this.stack[this.size()-1]
    }
    empty() {
        return this.stack.length == 0;
    }
    size() {
        return this.stack.length;
    }
}

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var backspaceCompare = function(s, t) {
    let stack1 = new Stack();
    let stack2 = new Stack();
    transfer(stack1, s);
    transfer(stack2, t);
    // 判断两个栈的长度是否相同,若不相同则不可能相等
    if(stack1.size() != stack2.size())return false;
    while(!stack1.empty()) {
        if(stack1.top() != stack2.top()) return false;
        stack1.pop();
        stack2.pop();
    }
    return true;
};
// 遍历判断是否为#,若是则出栈,否则进栈
var transfer = function(stack, str) {
    for(var i = 0; i < str.length; i++) {
        if(str[i] == '#') {
            // !stack.empty() && stack.pop();
            if(!stack.empty()) {
                stack.pop()
            }
        } else {
            stack.push(str[i]);
        }
    }
}

二、验证栈序列

946. 验证栈序列

给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

示例 1:

  • 输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
  • 输出:true
  • 解释:我们可以按以下顺序执行:
  • push(1), push(2), push(3), push(4), pop() -> 4,
  • push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例 2:

  • 输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
  • 输出:false
  • 解释:1 不能在 2 之前弹出。

提示:

  • 0 <= pushed.length == popped.length <= 1000
  • 0 <= pushed[i], popped[i] < 1000
  • pushed 是 popped 的排列。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/va… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

pushed中的元素一直入栈,直到有元素和popped中未检测的首个元素相等,出栈,则检测通过,进行下个元素的检测。

当pushed中所有元素都进栈了,然而栈顶不等于监测值时,说明popped的操作序列不对了。

代码实现

class Stack {
    constructor() {
        this.stack = []
    }
    push(x) {
        this.stack.push(x);
    }
    pop() {
        if(this.empty()) return;
        let top = this.top();
        this.stack.pop()
        return top;
    }
    top() {
        return this.stack[this.size()-1]
    }
    empty() {
        return this.stack.length == 0;
    }
    size() {
        return this.stack.length;
    }
}


/**
 * @param {number[]} pushed
 * @param {number[]} popped
 * @return {boolean}
 */
var validateStackSequences = function(pushed, popped) {
    let stack = new Stack();
    // 
    let j = 0;
    // 遍历poped
    for(let i = 0; i < popped.length; i++) {
        // 当pushed中有值,且stack为空或栈顶不等于poped[i]时
        while(j < pushed.length && (stack.empty() || stack.top() != popped[i])) {
            // 将pushed[i]入栈
            stack.push(pushed[j]);
            j++;
        }
        // 当因为j>=pushed.length跳出来时,如果栈顶不等于poped[i],那么可以判断poped的操作序列是不对的
        if(stack.top() != popped[i]) return false;
        stack.pop();
    }
    return true;
};