当前位置: 首页 > article >正文

代码随想录-刷题第十一天

232. 用栈实现队列

题目连接:232. 用栈实现队列

思路:一个栈作为输入栈,一个栈作为输出栈。在push数据的时候,直接将数据放到输入栈,在pop数据的时候,如果输出栈为空,将输入栈的数据全部导入到输出栈,如果输出栈不为空,直接pop输出栈。如果两个栈都为空,模拟队列为空。

class MyQueue {
    private Stack<Integer> s1, s2;

    public MyQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }

    /**
     * 添加元素到队尾
     */
    public void push(int x) {
        s1.push(x);
    }

    /**
     * 删除队头的元素并返回
     */
    public int pop() {
        // 先调用 peek 保证 s2 非空
        peek();
        return s2.pop();
    }

    /**
     * 返回队头元素
     */
    public int peek() {
        if (s2.isEmpty())
            // 把 s1 中元素全部压入 s2
            while (!s1.isEmpty())
                s2.push(s1.pop());
        return s2.peek();
    }

    /**
     * 判断队列是否为空
     */
    public boolean empty() {
        return s1.isEmpty() && s2.isEmpty();
    }
}

225. 用队列实现栈

题目连接:225. 用队列实现栈

思路:一个队列在模拟栈弹出元素的时候只要将队尾元素前面的所有元素重新塞到队尾,让队尾元素排到队头,此时再去弹出元素就是栈的顺序了。

class MyStack {
    Queue<Integer> q;
    int top_elem;

    public MyStack() {
        q = new LinkedList<>();
        top_elem = 0;
    }
    
    /**
     * 添加元素到栈顶
     */
    public void push(int x) {
        // x 是队列的队尾,是栈的栈顶
        q.offer(x);
        top_elem = x;
    }

    /**
     * 删除栈顶的元素并返回
     */
    public int pop() {
        int size = q.size();
        // 留下队尾 2 个元素
        while (size > 2) {
            q.offer(q.poll());
            size--;
        }
        // 记录新的队尾元素
        top_elem = q.peek();
        q.offer(q.poll());
        // 删除之前的队尾元素
        return q.poll();
    }

    /**
     * 返回栈顶元素
     */
    public int top() {
        return top_elem;
    }

    /**
     * 判断栈是否为空
     */
    public boolean empty() {
        return q.isEmpty();
    }
}

20. 有效的括号

题目连接:20. 有效的括号

思路:一次遍历,遇到左括号就入栈,遇到右括号就去栈中寻找最近的左括号,看是否匹配。遍历结束后栈为空,说明匹配成功。

时间复杂度O(n)

class Solution {
    public boolean isValid(String s) {
        Stack<Character> left = new Stack<>();
        for (char c : s.toCharArray()) {
            if (c == '(' || c == '{' || c == '[')
                left.push(c);
            else // 字符 c 是右括号
                if (!left.isEmpty() && leftOf(c) == left.peek())
                    left.pop();
                else
                    // 和最近的左括号不匹配
                    return false;
        }
        // 是否所有的左括号都被匹配了
        return left.isEmpty();
    }

    private char leftOf(char c) {
        if (c == '}') return '{';
        if (c == ']') return '[';
        return '(';
    }
}

1047. 删除字符串中的所有相邻重复项

题目连接:1047. 删除字符串中的所有相邻重复项

思路:为什么会想到用栈?因为和上一题有效括号一样,都是做消除操作。匹配问题是栈的强项。栈为什么适合做这种类似于爱消除的操作,因为栈记录了遍历数组当前元素时,前一个元素是什么。

时间复杂度O(n)

class Solution {
    public String removeDuplicates(String s) {
        // 将 res 当做栈
        // 也可以用 StringBuilder 来修改字符串,速度更快
        // StringBuilder res = new StringBuilder();
        StringBuffer res = new StringBuffer();
        // top为 res 的长度
        int top = -1;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 当栈中有字符时,
            // 并且当前字符和栈中字符相等,弹出栈顶字符,同时top--
            if (top >= 0 && res.charAt(top) == c) {
                res.deleteCharAt(top);
                top--;
            // 否则,将该字符入栈,同时top++
            } else {
                res.append(c);
                top++;
            }
        }
        return res.toString();
    }
}

另一种写法,执行用时更短

class Solution {
    public String removeDuplicates(String s) {
        StringBuilder res = new StringBuilder();
        // 转换成字符数组更方便
        char[] ch = s.toCharArray();
        int top = -1;
        for (char c : ch) {
            if(top >= 0 && c == res.charAt(top)) {
                res.deleteCharAt(top);
                top--;
            } else {
                res.append(c);
                top++;
            }
        }
        return res.toString();
    }
}


http://www.kler.cn/news/149197.html

相关文章:

  • CSS-常见元素显示模式总结
  • [Android]常见的数据传递方式
  • Spark---资源、任务调度
  • 【Linux下基本指令——(1)】
  • 【C 语言经典100例】C 练习实例13 - 水仙花数
  • python基础练习题库实验6
  • Vue3-toRaw 和 markRaw 函数
  • js相同字符串截取拼接
  • 牛客剑指offer刷题位运算篇
  • 八股文-如何理解Java中的多态
  • 管理后台系统,springboot+redis+nginx+html+bootstrap
  • UE5 中的computer shader使用
  • C++ 背包理论基础01 + 滚动数组
  • 【MySql】14- 实践篇(十二)-grant权限/分区表/自增Id用完怎么办
  • HassOS使用nmcli设置静态IPv4地址及网关、DNS
  • 对支付宝进行测试用例分析
  • .sketch的文件转.psd文件
  • Linux僵死进程及文件操作
  • 【ARM CoreLink 系列 8 -- SMMU 详细介绍-上半部】
  • 《微信小程序开发从入门到实战》学习三十六
  • springboot实战之stream API应用过滤不符合条件的数据
  • MySQL巧用公用表表达式(CTE)处理递归查询
  • 想学计算机视觉入门的可以看过来了
  • 牛客算法题 HJ100 等差数列 golang语言实现
  • QT配合CSS隐藏按钮
  • Springboot_文件下载功能(前端后端)
  • Kotlin学习——kt入门合集博客 kt里的委派模式Delegation kt里的特性
  • 基于C#实现Dijkstra算法
  • Java架构师软件架构开发
  • ⑨【Stream】Redis流是什么?怎么用?: Stream [使用手册]