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

2023-10-31 16:52

本文主要是介绍数据结构(三):栈及面试常考的算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、栈介绍

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 falsereturn false;       else st.pop(); // st.top() 与 s[i]相等,栈弹出元素}// 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return truereturn 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.chinasem.cn/article/316773

相关文章

数据库面试必备之MySQL中的乐观锁与悲观锁

《数据库面试必备之MySQL中的乐观锁与悲观锁》:本文主要介绍数据库面试必备之MySQL中乐观锁与悲观锁的相关资料,乐观锁适用于读多写少的场景,通过版本号检查避免冲突,而悲观锁适用于写多读少且对数... 目录一、引言二、乐观锁(一)原理(二)应用场景(三)示例代码三、悲观锁(一)原理(二)应用场景(三)示例

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要