代码随想录18

20. 有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 注意空字符串可被认为是有效字符串。

示例 1:

  • 输入: "()"
  • 输出: true

示例 2:

  • 输入: "()[]{}"
  • 输出: true

思路:这道题在以前编译原理课设制作编译器的时候遇到过

很明显这道题要用栈的思路先进后出

注意点:就是输入左边的符号的时候要把相应右边的符号压入栈,这样方便比较

#include <stack>
#include <string>
using namespace std;class Solution {
public:bool isValid(string s) {stack<char> st; // 初始化栈for (int i = 0; i < s.size(); i++) {if (s[i] == '(') {st.push(')'); // 如果是 '(',压入对应的右括号 ')'} else if (s[i] == '{') {st.push('}'); // 如果是 '{',压入对应的右括号 '}'} else if (s[i] == '[') {st.push(']'); // 如果是 '[',压入对应的右括号 ']'} else {// 如果是右括号,检查栈是否为空,或者栈顶是否匹配当前右括号if (st.empty() || st.top() != s[i]) {return false; // 不匹配直接返回 false}st.pop(); // 匹配成功,弹出栈顶元素}}// 最后检查栈是否为空,若为空说明所有括号匹配成功return st.empty();}
};

这是我自己写的代码:

思路:

  1. 栈的特点:后进先出
    栈的特点使得它可以快速判断当前字符是否与前一个字符相同,从而决定是否需要移除字符。

  2. 逐一遍历字符串
    遍历字符串的每个字符,对每个字符进行如下操作:

    • 如果栈为空,直接将字符压入栈中。
    • 如果栈非空,检查栈顶字符是否与当前字符相同:
      • 若相同:表示找到一对相邻重复字符,将栈顶字符弹出,移除这对字符。
      • 若不同:将当前字符压入栈中。
  3. 栈中的内容即为最终结果

    • 遍历完成后,栈中的字符就是所有消除了相邻重复字符后剩下的字符。
    • 注意:栈中的字符顺序是从栈底到栈顶,而实际字符串顺序是从左到右,因此需要反转栈中的内容以得到最终结果。

class Solution {
public:string removeDuplicates(string s) {stack<char> st; // 修正 "stacck" 为 "stack<char>"for (int i = 0; i < s.size(); i++) {if (st.empty() || st.top() != s[i]) { // 修正 "st==empty()" 为 "st.empty()",并且修正 "st.top" 为 "st.top()"st.push(s[i]);} else { // 如果字符与栈顶字符相同st.pop();}}// 将栈中的字符还原为字符串string result = "";while (!st.empty()) {result += st.top();st.pop();}reverse(result.begin(), result.end()); // 栈中字符顺序为倒序,需要反转return result;}
};

老师的做法的话就不用反转字符串

用字符串来模拟栈的话就可以直接找到字符串的顶和尾,并且弹出和压入

代码如下:

class Solution {
public:string removeDuplicates(string s) {string result = ""; // 用字符串模拟栈for (char c : s) {if (!result.empty() && result.back() == c) { // 如果栈顶与当前字符相同result.pop_back(); // 弹出栈顶} else {result.push_back(c); // 压入当前字符}}return result;}
};

50. 逆波兰表达式求值

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 + ,  - ,  * ,  / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例 1:

  • 输入: ["2", "1", "+", "3", " * "]
  • 输出: 9
  • 解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

  • 输入: ["4", "13", "5", "/", "+"]
  • 输出: 6
  • 解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

以下是我自己写的思路:

没想到的:

使用 std::stoi 将其转换为整数

  1. 逆波兰表达式的基本特点

    • 遇到数字时,将其压入栈中。
    • 遇到操作符时,从栈中弹出两个数字,进行计算,将计算结果重新压入栈。
  2. 步骤

    1. 遍历表达式列表 tokens
    2. 如果当前元素是数字:
      • 使用 std::stoi 将其转换为整数,压入栈中。
    3. 如果当前元素是操作符:
      • 弹出栈顶的两个数字,假设为 ba
      • 根据操作符执行计算:a + b, a - b, a * b, 或 a / b
      • 将计算结果压入栈中。
    4. 遍历结束后,栈顶元素即为最终结果。
  3. 注意事项

    • 运算顺序:对于减法和除法,弹出的第一个数字是右操作数,第二个数字是左操作数。
    • 操作数和操作符的输入顺序必须符合逆波兰表达式的规则。

#include <stack>
#include <vector>
#include <string>
#include <cstdlib> // for stoiusing namespace std;class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for (int i = 0; i < tokens.size(); i++) {// 判断是否为操作符if (tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/") {// 是数字,转换为整数并压入栈st.push(stoi(tokens[i]));} else {// 是操作符,弹出两个操作数int b = st.top(); st.pop();int a = st.top(); st.pop();// 执行相应的操作并将结果压入栈if (tokens[i] == "+") st.push(a + b);else if (tokens[i] == "-") st.push(a - b);else if (tokens[i] == "*") st.push(a * b);else if (tokens[i] == "/") st.push(a / b);}}// 返回最终结果return st.top();}
};

239. 滑动窗口最大值

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 

示例 1:

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       31 [3  -1  -3] 5  3  6  7       31  3 [-1  -3  5] 3  6  7       51  3  -1 [-3  5  3] 6  7       51  3  -1  -3 [5  3  6] 7       61  3  -1  -3  5 [3  6  7]      7

示例 2:

输入:nums = [1], k = 1
输出:[1]

下面是我自己写的

这个用数组的代码,代码时间复杂度为 O(n×k)O(n \times k)O(n×k),会导致在大数据量情况下性能不佳。

#include <vector>
#include <algorithm>
using namespace std;class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> result; // 存储结果// 检查边界条件if (nums.empty() || k <= 0) {return result;}for (int i = 0; i <= nums.size() - k; i++) {// 在每个滑动窗口中找到最大值int temp = nums[i];for (int j = 1; j < k; j++) {temp = max(temp, nums[i + j]);}result.push_back(temp);}return result;}
};

优化后的代码(使用双端队列提高效率):

如果你需要更高效的实现,可以用双端队列将复杂度优化到 O(n)O(n)O(n)。以下是推荐的高效实现:

#include <vector>
#include <deque>
using namespace std;class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> result;       // 存储结果deque<int> dq;            // 存储滑动窗口中可能的最大值下标for (int i = 0; i < nums.size(); i++) {// 移除窗口外的元素if (!dq.empty() && dq.front() < i - k + 1) {dq.pop_front();}// 移除队列中小于当前元素的所有元素while (!dq.empty() && nums[dq.back()] < nums[i]) {dq.pop_back();}// 添加当前元素下标dq.push_back(i);// 记录当前窗口的最大值if (i >= k - 1) {result.push_back(nums[dq.front()]);}}return result;}
};

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

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

相关文章

Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)

Vue Amazing UI 一个 Vue 3 组件库 使用 TypeScript&#xff0c;都是单文件组件 (SFC)&#xff0c;支持 tree shaking 有点意思 English | 中文 Vue Amazing UI 是一个基于 Vue 3、TypeScript、Vite 等最新技术栈开发构建的现代化组件库&#xff0c;包含丰富的 UI 组件和常…

git:指令集

以下是对这些 Git 新特性和命令的更详细解读和实际用例分析&#xff0c;帮助更好地理解它们的作用及适用场景&#xff1a; 1. git switch 和 git restore 背景&#xff1a; 传统上&#xff0c;git checkout 是一个多功能命令&#xff0c;用于切换分支、检出文件、创建分支等&…

C语言----指针

目录 1.概念 2.格式 3.指针操作符 4.初始化 1. 将普通变量的地址赋值给指针变量 a. 将数组的首地址赋值给指针变量 b. 将指针变量里面保存的地址赋值给另一个指针变量 5.指针运算 5.1算术运算 5.2 关系运算 指针的大小 总结&#xff1a; 段错误 指针修饰 1. con…

ElasticSearch系列(一)

一.了解ES、倒排索引、es的一些概念、安装es、kibana 二.DSL&#xff1b;索引库操作 三.Java RestClient&#xff1a;索引库操作 一、了解ES、倒排索引、es的一些概念、安装es、kibana kibana、logstash、beats Elasticserach 存储&#xff0c;计算 &#xff0c;搜索数据 –…

Python应用——将Matplotlib图形嵌入Tkinter窗口

Python应用——将Matplotlib图形嵌入Tkinter窗口 目录 Python应用——将Matplotlib图形嵌入Tkinter窗口1 模块简介2 示例代码2.1 Matplotlib嵌入Tkinter2.2 Matplotlib嵌入Tkinter并显示工具栏 1 模块简介 Tkinter是Python的标准GUI&#xff08;图形用户界面&#xff09;库&…

C#语言的网络编程

C#语言的网络编程 引言 随着互联网的飞速发展&#xff0c;网络编程成为了软件开发中的一个重要领域。C#语言作为一种现代编程语言&#xff0c;凭借其丰富的类库、良好的可读性和强大的功能&#xff0c;广泛应用于开发各种网络应用程序。无论是Windows应用、Web应用还是云服务…

软件工程大复习之(四)——面向对象与UML

4.1 面向对象概述 面向对象&#xff08;OO&#xff09;是一种编程范式&#xff0c;它将数据和处理数据的方法封装在对象中。面向对象的主要概念包括&#xff1a; 对象&#xff1a;实例化的数据和方法的集合。类&#xff1a;对象的蓝图或模板。封装&#xff1a;隐藏对象的内部…

【linux基础I/O(2)】理解文件系统|文件缓冲区|软硬链接|动静态库

目录 前言1. 理解C语言的缓冲区2. 对文件系统的初认识3. 理解软硬链接1. 软硬链接的特征2.软硬链接的作用 4. 理解动静态库5. 总结 前言 对于文件来讲,有打开的在内存中的文件,也有没有打开的在磁盘上文件,上一篇文章讲解的是前者,本篇文章将带大家了解后者! 本章重点: 本篇文…

什么是Redis的渐进式ReHash?

文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ Redis 的渐进式 rehash 是一…

Linux应用软件编程--网络通信(udp协议,tcp协议)

网络通信&#xff1a;不同主机&#xff0c;进程间通信&#xff0c;分为广域网和局域网 OSI 七层模型&#xff1a;是一种理论模型 应用层&#xff1a;通信传输的数据内容 http、FTP、TFTP、MQTT 表述层&#xff1a;数据加密&#xff0c;解密操作&#xff0c;压缩&#xff…

深度学习,训练集准确率高,但验证集准确率一直不上升,很低的问题

在训练过程中&#xff0c;训练集的准确率稳步上升&#xff0c;但是验证集的准确率一直在40%左右徘徊&#xff0c;从网上搜索可能的原因有&#xff1a; 1、学习率太小&#xff0c;陷入局部最优。 2、数据量太小&#xff08;4000多条数据&#xff0c;应该还可以吧&#xff09; …

【C++】构造函数与析构函数

写在前面 构造函数与析构函数都是属于类的默认成员函数&#xff01; 默认成员函数是程序猿不显示声明定义&#xff0c;编译器会中生成。 构造函数和析构函数的知识需要建立在有初步类与对象的基础之上的&#xff0c;关于类与对象不才在前面笔记中有详细的介绍&#xff1a;点我…

期刊选择【生物医学工程】

所有数据来源letpub Academic radiology【共一共通&#xff0c;速度√杠杠的】 【LetPub】ACADEMIC RADIOLOGY 影响因子3.800分&#xff0c;是几区&#xff0c;2023-2024年期刊投稿经验分享&#xff0c;ACADEMIC RADIOLOGY主页&#xff0c;推荐审稿人、编辑&#xff0c;审稿…

【简博士统计学习方法】3. 统计学习方法的三要素

3. 统计学习方法的三要素 3.1 监督学习的三要素 3.1.1 模型 假设空间&#xff08;Hypothesis Space&#xff09;&#xff1a;所有可能的条件概率分布或决策函数&#xff0c;用 F \mathcal{F} F表示。 若定义为决策函数的集合&#xff1a; F { f ∣ Y f ( X ) } \mathcal{F…

Flink如何设置合理的并行度

一个Flink程序由多个Operator组成(source、transformation和 sink)。 一个Operator由多个并行的Task(线程)来执行, 一个Operator的并行Task(线程)数目就被称为该Operator(任务)的并行度(Parallel)。即并行度就是相对于Operator来说的。 合理设置并行度可以有效提高Flink作业…

【PostgreSQL】PG多实例部署

注释 PGPORT 和 PGDATA 环境变量 su - postgresvim ~/.bash_profileexport PATH=/usr/local/pgsql/bin:$PATH export MANPATH=/usr/local/pgsql/share/man:$MANPATH export LD_LIBRARY_PATH=/usr/local/pgsql/lib #export PGPORT=5432 export LANG=en_US.UTF8 export PS1=&quo…

【llm/ollama/qwen】在本地部署qwen2.5-coder并在vscode中集成使用代码提示功能

说在前面 操作系统&#xff1a;windows11ollama版本&#xff1a;0.5.4vscode版本&#xff1a;1.96.2continue插件版本&#xff1a;0.8.66 ollama安装 访问官网&#xff0c;点击下载安装即可 默认装在了C盘&#xff0c;比较蛋疼&#xff1b;但是可以指定路径安装&#xff1a;Ol…

PHP零基础入门笔记

表达式&#xff1a;任何有值的东西就是表达式 php可以解析双引号&#xff0c;不可以解析单引号&#xff0c;双引号中引用变量可以输出引用变量的值&#xff0c;但是单引号不可以 1.变量和变量的销毁 unset(变量名) //销毁变量 变量是严格区分大小写的&#xff0c;在php中…

《CPython Internals》阅读笔记:p1-p19

《CPython Internals》学习第 1 天&#xff0c;p1-p19 总结&#xff0c;总计 19 页。 一、技术总结 无。 二、英语总结(生词&#xff1a;2) 1.humble vs humbled (1)humble: humus(“earth”) adj. 字面意思是“on the ground”, 后面引申为“lowly in kind, state, cond…

macos安装java8

下载 dmg方式安装 安装 双击pkg运行 输入java -version验证 配置环境变量 cd ~ ls -a输入 ls -a后查看是否已经存在.bash_profile文件&#xff0c;如果已经存在就不需要创建&#xff0c;如果不存在&#xff0c;继续执行下方命令创建文件 touch .bash_profile /usr/l…