算法练习-栈和队列(二)

news2025/7/19 16:46:02

算法练习-栈和队列(二)

文章目录

  • 算法练习-栈和队列(二)
    • 1.计算器
      • 1.1 题目
      • 1.2 题解
    • 2. 删除字符串中所有相邻重复项
      • 2.1 题目
      • 2.2 题解
    • 3 栈的压入、弹出序列
      • 3.1 题目
      • 3.2 题解
    • 4 每日温度
      • 4.1 题目
      • 4.2 题解
        • 4.2.1 暴力解法(超出时间限制)
        • 4.2.2单调栈
    • 5 接雨水(hard)
      • 5.1 题目
      • 5.2 题解
        • 5.2.1 暴力解法
        • 5.2.2 前缀/后缀统计解法
        • 5.2.3 单调栈

1.计算器

链接:https://leetcode.cn/problems/calculator-lcci

1.1 题目

给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。

表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。

示例 1:

输入: “3+2*2”
输出: 7
示例 2:

输入: " 3/2 "
输出: 1
示例 3:

输入: " 3+5 / 2 "
输出: 5

1.2 题解

创建了两个栈,一个存储运算数,另一个存储运算符

如何进行入栈和出栈,见prior

class Solution {
    public int calculate(String s) {
        Stack<Integer> nums = new Stack<>();
        Stack<Character> ops = new Stack<>();
        int i = 0;
        int n = s.length();
        while (i < n) {
            char c = s.charAt(i);
            if (c == ' ') {
                i++;
            } else if (isDigit(c)) {
                int num = 0;
                while (i < n && isDigit(s.charAt(i))) {
                    num = num * 10 + (s.charAt(i) - '0');
                    i++;
                }
                nums.push(num);
            } else {
                if (ops.isEmpty() || prior(c, ops.peek())) {
                    ops.push(c);
                } else {
                    while (!ops.isEmpty() && !prior(c, ops.peek())) {
                        fetchAndCal(nums, ops);
                    }
                    ops.push(c);
                }
                i++;
            }
        }

        while(!ops.isEmpty()) {
            fetchAndCal(nums, ops);
        }

        return nums.pop();
    }

    public boolean prior(char a, char b) {
        if ((a == '*' || a == '/') && (b == '+' || b == '-')) {
            return true;
        }
        return false;
    }

    public int cal(char op, int num1, int num2) {
        switch(op) {
            case '+' : return num1 + num2;
            case '-' : return num1 - num2;
            case '*' : return num1 * num2;
            case '/' : return num1 / num2;
        }
        return -1;
    }

    public boolean isDigit(char c) {
        return c >= '0' && c <= '9';
    }

    public void fetchAndCal(Stack<Integer> nums, Stack<Character> ops) {
        int num2 = nums.pop();
        int num1 = nums.pop();
        char op = ops.pop();
        int res = cal(op, num1, num2);
        nums.push(res);
    }
}



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

链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string

2.1 题目

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:“abbaca”
输出:“ca”
解释:
例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。

2.2 题解

class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> deque = new LinkedList<>();
        int n = 0;
        int num = s.length();
        while (n < num) {
            char c = s.charAt(n);
            if (deque.isEmpty() || deque.peekLast() != c) {
                deque.addLast(c);
            } else {
                deque.pollLast();
            }
            n++;
        }
        StringBuilder sb = new StringBuilder();
        while (!deque.isEmpty()) {
            sb.append(deque.pollFirst());
        }
        return sb.toString();
    }
}

3 栈的压入、弹出序列

3.1 题目

链接:https://leetcode.cn/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。

示例 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 之前弹出。

3.2 题解

按照给定的入栈和出栈的元素进行操作,如果不能正常入栈和出栈,则序列错误

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> stack = new Stack<>();
        int i = 0;
        int j = 0;
        int k = 0;
        while (k < pushed.length + popped.length) {
            k++;
            // 如果栈不为空并且出栈序列有元素,栈顶元素等于出栈序列的元素
            // 出栈
            if (!stack.isEmpty() && j < popped.length && stack.peek() == popped[j]) {
                stack.pop();
                j++;
                continue;
            }
            
            // 入栈
            if (i < pushed.length) {
                stack.push(pushed[i]);
                i++;
                continue;
            }
            return false;
        }
        return true;
    }
}

4 每日温度

链接:https://leetcode.cn/problems/daily-temperatures

4.1 题目

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例 2:

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
示例 3:

输入: temperatures = [30,60,90]
输出: [1,1,0]

4.2 题解

4.2.1 暴力解法(超出时间限制)

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int n = temperatures.length;
        int[] result = new int[n];
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; j++) {
                if (temperatures[j] > temperatures[i]) {
                    result[i] = j - i;
                    break;
            }
        }
    }
    return result;
}
}

4.2.2单调栈

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int n = temperatures.length;
        int result[] = new int[n];
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < n; i++) {
            while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) {
                int idx = stack.peek();
                result[idx] = i - idx;
                stack.pop();
            }
            stack.push(i);
        }
        return result;
    }
}

5 接雨水(hard)

链接:https://leetcode.cn/problems/trapping-rain-water

5.1 题目

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

请添加图片描述

示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

5.2 题解

5.2.1 暴力解法

每个主子上的承载水量=min(左侧最高柱子lh,右侧最高柱子rh)-这个柱子高度h的总接水量=每个柱子之上的承载水量总和

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int result = 0;
        // 遍历每个柱子,找到左面最高的柱子和右面最高的柱子
        for (int i = 0; i < n - 1; ++i) {
            int lh = 0;
            for (int j = 0; j < i; j++) {
                if (height[j] > lh) {
                    lh = height[j];
                }
            }
            int rh = 0;
            for (int j = i + 1; j < n; j++) {
                if (height[j] > rh) {
                    rh = height[j];
                }
            }

            int carry = Math.min(lh, rh) - height[i];
            if (carry < 0) {
                carry = 0;
            }
            result += carry;
        }
        return result;
    }
}

5.2.2 前缀/后缀统计解法

利用空间换时间

创建两个数组,分别存储当前位置左侧最大高度和右侧最大高度

先循环填充两个数组

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        // 前缀max
        int[] lmax = new int[n];
        int max = 0;
        for (int i = 0; i < n; ++i) {
            lmax[i] = Math.max(max, height[i]);
            max = lmax[i];
        }

        // 后缀max
        int[] rmax = new int[n];
        max = 0;
        for (int i = n - 1; i >= 0; --i) {
            rmax[i] = Math.max(max, height[i]);
            max = rmax[i];
        }

        int result = 0;
        for (int i = 0; i < n - 1; i++) {
            result += Math.min(lmax[i], rmax[i]) - height[i];
        }
        return result;
    }
}

5.2.3 单调栈

前面两种方法按照垂直计算,该方法水平计算,一层一层计算存水量

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int result = 0;
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < n; i++) {
            if (stack.isEmpty()) {
                stack.push(i); // 存下标
                continue;
            }
            while (!stack.isEmpty()) {
                int top = stack.peek();
                if (height[top] >= height[i]) {
                    stack.push(i);
                    break;
                } else { // 找到凹槽了
                    top = stack.pop();
                    if (stack.isEmpty()) {
                        stack.push(i);
                        break;
                    }
                    int left = stack.peek();
                    int h = Math.min(height[left], height[i]) - height[top];
                    int w = i - left - 1;
                    result += h * w;
                }
            }
        }
        return result;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/369382.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

i2c子系统

i2c 硬件协议 Linux 应用层读写i2c 数据 在Linux系统上&#xff0c;不仅可以在内核中使用 i2c 总线发送、接收数据&#xff0c;同时也支持应用层使用i2c 总线发送、接收。 如果在内核中使能了drivers/i2c/i2c-dev.c 配置&#xff0c;内核就会为每一个i2c 控制器生成一个/dev/…

如何使评论具有可操作性?取悦客户的指南

永远不要低估承认的力量。 当品牌与客户互动时&#xff0c;认可会带来更好的关系和更好的沟通。与买家和客户建立更多的个人联系意味着品牌需要证明他们支持他们的产品和客户。评论是利用客户分享他们的故事的那些时刻的绝佳机会。 为什么评论在 SaaS 中至关重要 在 B2B 软件的…

robot framework + python实现http接口自动化测试框架

前言 下周即将展开一个http接口测试的需求&#xff0c;刚刚完成的java类接口测试工作中&#xff0c;由于之前犯懒&#xff0c;没有提前搭建好自动化回归测试框架&#xff0c;以至于后期rd每修改一个bug&#xff0c;经常导致之前没有问题的case又产生了bug&#xff0c;所以需要…

金仓数据库安装

一、麒麟操作系统安装金仓数据库 操作系统 DISTRIB_IDKylin DISTRIB_RELEASEV10 DISTRIB_CODENAMEjuniper 按照安装文档的步骤安装&#xff0c;记得记住设置的数据库的用户名、密码 二、window安装连接数据库的工具软件 三、jdbc连接数据库 &#xff08;1&#xff09;连接工…

分享10个非常不错的封面设计模板

封面设计很关键&#xff0c;这决定了用户是否愿意更进一步了解作品或者产品。从布局结构到文字排版和配色&#xff0c;好的封面设计一定是涉及多方面的综合加持。今天给大家整理很多优质的封面设计案例&#xff0c;可以免费商用&#xff0c;包括了&#xff1a;磨砂风格封面、玻…

nodejs+vue停车场停车位短租系统vscode

目 录前端技术&#xff1a;nodejsvueelementui 前端&#xff1a;HTML5,CSS3、JavaScript、VUE 1、 node_modules文件夹(有npn install产生) 这文件夹就是在创建完项目后&#xff0c;cd到项目目录执行npm install后生成的文件夹&#xff0c;下载了项目需要的依赖项。 2、…

LoRaWAN模块在智能停车中的应用

智能停车是指利用自动驾驶技术&#xff0c;帮助驾驶员迅速找到可使用的停车位&#xff0c;并为驾驶员提供准确的驾驶路径。智能停车系统的高级体系结构包括四大要素&#xff1a;(1)“车位锁”的驻车刹车。(2)与“车位锁”相连的一种网络关卡。(3)一个获取停车场状况并发布一个控…

设计模式—策略(Strategy)模式

一、概述策略模式的用意是针对一组算法&#xff0c;将每一个算法封装到具有共同接口的独立的类中&#xff0c;从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化使用策略模式可以把行为和环境分割开来。环境类负责维持和查询行为类&#xff0c;…

时序预测 | MATLAB实现LSTM-SVR(长短期记忆神经网络-支持向量机)时间序列预测

时序预测 | MATLAB实现LSTM-SVR(长短期记忆神经网络-支持向量机)时间序列预测 目录时序预测 | MATLAB实现LSTM-SVR(长短期记忆神经网络-支持向量机)时间序列预测效果一览基本介绍模型介绍LSTM模型SVR模型LSTM-SVR模型程序设计参考资料致谢效果一览 基本介绍 本次运行测试环境MA…

黑客入门(超级详细版)

据我了解&#xff0c;“黑客”大体上应该分为“正”、“邪”两类&#xff0c;正派黑客依靠自己掌握的知识帮助系统管理员找出系统中的漏洞并加以完善&#xff0c;而邪派黑客则是通过各种黑客技能对系统进行攻击、入侵或者做其他一些有害于网络的事情&#xff0c;因为邪派黑客所…

利用sim函数在m文件里运行Simulink模型

目录前言准备参考文章第一步第二步第三步前言 最近在使用Simulink做仿真的时候&#xff0c;需要在m文件里运行Simulink模型&#xff0c;用到了sim函数&#xff0c;记录一下 准备 MATLAB R2022a 参考文章 matlab函数sim,matlab sim函数究竟是怎么用的&#xff1f; Matlab中…

在SNAP中用sentinel-1数据制作DEM

在SNAP中用sentinel-1数据制作DEM0 SNAP 简介1 SNAP和snaphu的安装1.1 SNAP安装1.2 snaphu安装1.2.1 Windows系统安装snaphu1.2.2 Linux系统中安装snaphu2 基于InSAR技术制作DEM的基本原理3 数据下载&#xff0c;包括sentinel-1 SLC数据、参考DEM数据、精密轨道数据3.1 sentine…

LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法

LeetCode经典算法题&#xff1a;井字游戏优势洗牌Dota2参议院java解法 井字游戏优势洗牌Dota2参议院1 井字游戏题目描述解题思路与代码2 优势洗牌题目描述解题思路与代码3 Dota2参议院题目描述解题思路与代码1 井字游戏 题目描述 用字符串数组作为井字游戏的游戏板 board&…

Linux 服务器CPU超高如何快速定位

前言 在生产环境中有时会遇见服务器CPU超高的问题&#xff0c;特别是重大版本发布后如果有内存泄露很容出现CPU超高&#xff0c;严重可能会达到100%。现在我们使用的服务器都是多核CPU&#xff0c;当出现CPU告警我们需要及时发现问题代码并处置&#xff0c;不然严重情况下会导致…

【阿旭机器学习实战】【36】糖尿病预测---决策树建模及其可视化

【阿旭机器学习实战】系列文章主要介绍机器学习的各种算法模型及其实战案例&#xff0c;欢迎点赞&#xff0c;关注共同学习交流。 【阿旭机器学习实战】【36】糖尿病预测—决策树建模及其可视化 目录【阿旭机器学习实战】【36】糖尿病预测---决策树建模及其可视化1. 导入数据并…

Datacom-HCIE考试经验分享

我是誉天Datacom秦同学。作为誉天众多通过Datacom-HCIE考试的学员之一&#xff0c;我感到很荣幸。 首先说说自学的感受吧&#xff1a; 我是从2020年开始接触网络行业的&#xff0c;听单位的前辈说华为的HCIE认证是行业含金量最高的证书&#xff0c;从那时起心里就种下了一个“I…

用 Visual Studio 升级 .NET 项目

现在&#xff0c;你已可以使用 Visual Studio 将所有 .NET 应用程序升级到最新版本的 .NET&#xff01;这一功能可以从 Visual Studio 扩展包中获取&#xff0c;它会升级你的 .NET Framework 或 .NET Core 网页和桌面应用程序。一些项目类型仍正在开发中并将在不久的未来推出&a…

spring Bean的生命周期 IOC

文章目录 1. 基础知识1.1 什么是 IoC ?2. 扩展方法3. 源码入口1. 基础知识 1.1 什么是 IoC ? IoC,控制反转,想必大家都知道,所谓的控制反转,就是把 new 对象的权利交给容器,所有的对象都被容器控制,这就叫所谓的控制反转。 IoC 很好地体现了面向对象设计法则之一 —…

适合运动时戴的蓝牙耳机有哪些、2023热门运动耳机推荐

在运动时听音乐&#xff0c;歌曲里的节奏、歌词都可以改变人的心态以及分散注意力&#xff0c;还能有效提升运动后的效果。在运动中听音乐&#xff0c;已经变为了一种随处可见的习惯。那么一款好的运动耳机&#xff0c;可以让运动更有激情&#xff0c;也能更好地享受运动的乐趣…

Pikachu靶场(暴力破解)

目录标题暴力破解&#xff08;登录&#xff09;基于表单的暴力破解验证码绕过(on server)验证码绕过(on client)token防爆破?上学期用这个靶场写过作业&#xff0c;现在抽空给它过一遍&#xff0c;由于需要抓包&#xff0c;从而通过小皮&#xff0c;使用本地&#xff08;127.0…