数据结构(三):栈及面试常考的算法

news2024/12/30 2:08:16

一、栈介绍

1、定义

栈也是一种数据呈线性排列的数据结构,不过在这种结构中,我们只能访问最新添加的数据。从栈顶放入元素的操作叫入栈,取出元素叫出栈

2、优缺点及使用场景

优点:高效的操作、简单易用、空间效率高等

缺点:局限性、容量限制、内存管理、不支持随机访问等。

使用场景:递归算法、括号匹配、表达式求值等。

3、基本操作

Push--在顶部插入一个元素

Pop--返回并移除栈顶元素

isEmpty--如果栈为空,则返回true

Top--返回顶部元素,但并不移除它

二、常考算法

1、使用栈计算后缀表达式

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

示例:输入: ["10", "6", "9", "3", "+", "-11", " * ", "/", " * ", "17", "+", "5", "+"],输出: 22

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。

  • 适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。

#include<stack>
#include<vector>
#include<string>
#include<iostream>
using namespace std;

int evaluate_postfix(vector<string> v){
    stack<long long> st;
    for(int i = 0; i < v.size(); i++){
        if (v[i] == "+" || v[i] == "-" || v[i] == "*" || v[i] == "/"){
            long long num1 = st.top();
            st.pop();
            long long num2 = st.top();
            st.pop();
            if(v[i] == "+") st.push(num2 + num1);
            if(v[i] == "-") st.push(num2 - num1);
            if(v[i] == "*") st.push(num2 * num1);
            if(v[i] == "/") st.push(num2 / num1);
        }
        else{
            st.push(stoll(v[i]));
        }
    }
    int result = st.top();
    st.pop();
    return result;
}

int main(){
    vector<string> v = {"10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"};
    int res;
    res = evaluate_postfix(v);
    cout << res;
}

 

2、对栈的元素进行排序

题目:input:[3, 1, 4, 2, 5]  output:[5, 4, 3, 2, 1]

思路:从原始栈中取出元素,将其插入到结果栈中的正确位置,以实现排序。在Python中,使用了while循环和pop操作,而在C++中使用了while循环和toppop操作。最终,返回的结果栈中包含了排序好的元素。

#include<stack>
#include<iostream>
using namespace std;
stack<int> sort_stack(stack<int> input_stack){
    stack<int> result_stack;
    while(!input_stack.empty()){
        int temp = input_stack.top();
        input_stack.pop();

        while(!result_stack.empty() && result_stack.top() < temp){
            input_stack.push(result_stack.top());
            result_stack.pop();
        }
        result_stack.push(temp);
    }
    return result_stack;

}

int main() {
    stack<int> input_stack;
    input_stack.push(3);
    input_stack.push(1);
    input_stack.push(4);
    input_stack.push(2);
    input_stack.push(5);

    stack<int> sorted_stack = sort_stack(input_stack);

    while (!sorted_stack.empty()) {
        cout << sorted_stack.top() << " ";
        sorted_stack.pop();
    }

    return 0;
}

3、判断表达式是否括号平衡

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

示例:input:"([{}]()",output:False;

思路:主要分为以下三种情况:

(1)已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false。

(2)遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false。

(3)遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false。

技巧:在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了。

#include<stack>
#include<string>
#include<iostream>
using namespace std;

bool isvalid(string s){
    if (s.size() % 2 == 1) // 如果s的长度为奇数,一定不符合要求
        return false;
    
    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
            // 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
            return false;       
        else st.pop(); // st.top() 与 s[i]相等,栈弹出元素
        
    }
    // 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
    return st.empty();

}

// 当bool类型的值为0时,它表示false,而当bool类型的值非零时,它表示true
int main(){
    bool s,s1,s2,s3;
    s = isvalid("([{}]()");
    cout << s << endl;
    s1 = isvalid("([{}}}");
    cout << s1<< endl;
    s2 = isvalid("([{}])))");
    cout << s2<< endl;
    s3 = isvalid("{[]}");
    cout << s3; 
}

  • 时间复杂度: O(n)
  • 空间复杂度: O(n)

 

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

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

相关文章

【C语言实现扫雷小游戏——可展开一片】

文章目录 1. 游戏分析和设计1.1扫雷游戏的功能说明1.2数据结构的分析与设计 2.代码实现2.1基本框架2.2初始化棋盘2.3打印棋盘2.4布置雷2.4统计周围雷的个数2.5排查雷2.6展开一片 3.完成代码3.1game.h3.2 game.c3.3test.c 学习完了函数和数组&#xff0c;让我们做个扫雷小游戏巩…

怎样才能把视频号的视频保存到相册,怎么下载视频号视频两个方法轻松解决

在微信客户端想要下载视频号视频却不知道怎么保存到本地相册&#xff1f;让不少网友犯了难&#xff0c;不用在纠结怎么样才可以将视频号视频下载下来&#xff0c;今天就分享两个小程序将视频号视频提取出来&#xff0c;另外在告诉大家一个下载技巧&#xff0c;一定要看到到结尾…

【Leetcode】 94. 二叉树的中序遍历

给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xff1a;root [1] 输出&#xff1a;[1] 提…

低代码PAAS加速推进企业数字化转型

无论是“十四五”规划从国家层面提出的“加快数字化发展 建设数字中国”&#xff0c;还是后疫情时代企业自身的感受&#xff0c;数字化转型已成为必答题。当前 企业 业务场景化、线上趋势愈加明显&#xff0c;越来越多并发的数字化应用场景&#xff0c;而原有集中式架构扩展能力…

图片去除水印文字怎么去除?这几个方法快来收藏

图片怎么去除水印文字&#xff1f;现在嘛&#xff0c;图片已经成了我们生活和工作里必不可少的一部分&#xff0c;可是有时候看图的时候&#xff0c;总会碰到一些带水印的图片&#xff0c;这些水印总是搞得图片看起来不那么爽&#xff0c;所以很多人都想知道图片怎么去除水印文…

力扣:145. 二叉树的后序遍历(Python3)

题目&#xff1a; 给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 示例&#xff1a; 示例 1&#xff1…

快速了解ClickHouse!

简介 ClickHouse是一个开源列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;用于在线分析处理&#xff08;OLAP&#xff09;&#xff1a; 列式存储&#xff1a;与传统的行式数据库不同&#xff0c;ClickHouse以列的形式存储数据&#xff0c;这使得在分析大量数据时…

3.1、Linux开发工具之vim编辑器

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 前言&#xff1a; 插入模式 底行模式 命令模式 前言&#xff1a; 没有进行配置的vim编辑器在写代码时和记事本没什么两样&#xff0c;所以最开始我们可以先下载一个插件&#xff0c;在Linux下两行指令的问题&…

表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信你对这篇博客也感兴趣o (ˉ▽ˉ&#xff1b;) 用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证&#xff08;带前后端源码&#xff09;全方位全流程超详细教程 目录 项目前端页面展…

十种排序算法(1) - 准备测试函数和工具

1.准备工作 我们先写一堆工具&#xff0c;后续要用&#xff0c;不然这些写在代码里可读性巨差 #pragma once #include<stdio.h>//为C语言定义bool类型 typedef int bool; #define false 0 #define true 1//用于交互a和b inline void swap(int* a, int* b) {/*int c *a…

Kibana无法启动 kibana_task_manager search_phase_execution_exception 问题解决

今天服务器重启以后&#xff0c;发现无法启动Kibana服务了&#xff0c;在网上也是把错误搜索了半天&#xff0c;尝试了那些命令&#xff0c;但是执行删除命令时居然报错了。后来&#xff0c;仔细观察后&#xff0c;发现是删除方式不太正确&#xff0c;需要改一下删除命令才能正…

Java on Azure Tooling 9月更新|Azure OpenAI 服务和 Playground 支持及更多

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 开发者工具九月份更新。在本次更新中&#xff0c;我们将介绍对 Azure OpenAI 服务和 Playground 的支持&#xff0c;开发…

python创建个人交易策略

编写您的第一个交易策略的综合教程。 介绍 创建个人交易策略在家庭交易者和/或 Python 爱好者中变得越来越流行。本文将介绍交易策略的完整生命周期:从获取市场数据开始,计算技术指标,生成交易信号,最后评估策略的有效性。 我们将使用 Kraken API 中的美元 价格,并基于移…

Vue 报错error:0308010C:digital envelope routines::unsupported

export NODE_OPTIONS--openssl-legacy-provider linux 可以解决

dbeaver配置es连接org.elasticsearch.xpack.sql.jdbc.EsDriver

查看目标es服务版本&#xff0c;下载对应驱动

GEO生信数据挖掘(十一)STRING数据库PPI蛋白互作网络 Cytoscape个性化绘图【SCI 指日可待】

GEO生信数据挖掘&#xff08;十&#xff09;肺结核数据-差异分析-WGCNA分析&#xff08;900行代码整理注释更新版本&#xff09; 通过 前面十篇文章的学习&#xff0c;我们应该已经可以获取到一个”心仪的基因列表“了&#xff0c;相较于原始基因数量&#xff0c;这个列表的数…

解决方案|法大大电子合同加速互联网家装服务升级

随着互联网的快速发展以及政策的不断推动&#xff0c;家装行业“互联网”趋势也不断凸显。行业内很多企业已经开始在全链条业务中使用电子合同&#xff0c;基于电子合同合规化、无纸化、线上化、智能化的价值赋能&#xff0c;实现家装从需求沟通、家装设计、选材、装修施工、验…

如何在mac 安装 cocos 的 android环境

基本概念&#xff1a; Java: Java 是一种编程语言&#xff0c;由Sun Microsystems&#xff08;现在是 Oracle Corporation&#xff09;开发。Java 是一种跨平台的语言&#xff0c;可以用于开发各种应用程序&#xff0c;包括 Android 应用程序。Android 应用程序的核心代码通常用…

会声会影2024永久激活序列号密钥 CDR Keygens 2024通用注册机

Corel All Products Universal Keygens 2024通用注册机是一款非常实用的激活工具&#xff0c;专门用于激活Corel全系列产品。尤其是被广泛使用的CorelDRAW作图软件和Corel VideoStudio会声会影视频编辑处理软件。小编也是一直关注由X-Force团队制作的注册机&#xff0c;目前已更…

Vue中动态增加表单项的方法

<!-- 需求 1 根据点击添加 生成表格数据 2 动态添加 表单-->点击添加生成对应动态表单 HTML <template><div class"main"><!-- 动态添加 --><div v-for"(item, index) in dataResult" :key"index"><a-form-mo…