目录

  • 什么是栈?
  • 题目类型
  • 顺序栈
  • 实践题目
    • [155. 最小栈](https://leetcode-cn.com/problems/min-stack/)
    • [42. 接雨水](https://leetcode-cn.com/problems/trapping-rain-water/)
    • [71. 简化路径](https://leetcode-cn.com/problems/simplify-path/)
    • [496. 下一个更大元素 I](https://leetcode-cn.com/problems/next-greater-element-i/)
    • [682. 棒球比赛](https://leetcode-cn.com/problems/baseball-game/)
    • [1021. 删除最外层的括号](https://leetcode-cn.com/problems/remove-outermost-parentheses/)
    • [341. 扁平化嵌套列表迭代器](https://leetcode-cn.com/problems/flatten-nested-list-iterator/)
    • [331. 验证二叉树的前序序列化](https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree/)
    • [1081. 不同字符的最小子序列](https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters/)

什么是栈?

是一个运算受限制的线性表,只能在表尾进行插入和删除,也就是先进后出,后进先出。(新手建议搜一本算法图解,讲的很明白)

题目类型

原理学习:155、71、682、341
单调栈:42、496、1081
辅助栈(只是用来计数的一个工具):1021、331
个人感觉没有新类型的,基本上就不重复记录题目了。

顺序栈

理解的话百度百科就可以,俺也是记笔记,怕误导你们。链接
顺序栈的适用情况(算法太多总结一下):
有明显的排序现象,或者是找左边啊右边啊第一个最大(最小)的情况。

实践题目

155. 最小栈

struct Node{int val;int min;Node *next;
};
//建立结构体,写入题目要求的功能
class MinStack {private:
Node* head;
public:MinStack() { head = nullptr;}//构造函数void push(int x) {if(head != NULL){int temp = (head -> min > x)? x : head -> min;Node *node = new Node();node -> min = temp;node -> val = x;node -> next = head;head = node;}//这里使用头插else{head = new Node();head -> val = x;head -> min = x;head -> next = nullptr;}}void pop() {head = head ->next;}int top() {return head -> val;}int getMin() {return head -> min;}
};

42. 接雨水

这个用单调递减栈:
稍微讲一下单调递减栈和单调递增栈:
(以单调递减栈为例)
1.若数据小于栈顶元素,则入栈。
2.如果数据比栈顶元素大,那么栈顶元素出栈,一直到数据比栈顶元素小为止。

打个比方:4312
4,3,1正常入栈
到2,和1比,1出栈,和3比,比3小,就出结果啦。

这道题我们只需要求有水滴的地方的面积,所以我们栈里存的数据是数组的下标(当然有其他解法,但是我这里用栈)

class Solution {public:int trap(vector<int>& height) {stack<int> num;int sum = 0;for(int i = 0;i < height.size();i++){while(!num.empty() && height[num.top()] < height[i]){int val = height[num.top()];num.pop();if(num.empty()) break;int l = i - num.top() - 1;int h = min(height[i],height[num.top()]) - val;sum += l * h;}num.push(i);}return sum;}
};

71. 简化路径

读完题目和例子,我得到的信息:
1、如果栈顶是/下一个要入栈的数据也是/那么栈顶出栈,下一个数据正常入栈。
2、如果栈顶是/(不排除例子乱输入a…这种情况)下一个要入栈的数据是…则数据全部出栈,下一个数据入栈。
3、如果栈顶是/,下一个要入栈数据是.那么栈顶出栈,而且继续出栈到下一个栈顶为/
4、在程序运行最后,判断栈顶是否是/,如果是就出栈。
怎么说呢,我们只需要判断两个/之间的东西是什么,再做相应操作就好了。

class Solution {public:string simplifyPath(string path) {path += '/';stack<string> stk;string str;for(char m : path){if(m == '/'){//如果str为.那么直接清除str即可//如果str为..那么stk把上一个数据给出栈(这里有特殊情况/../需要判断是否为空栈)//其他情况就把数据读进去,注意我这么写'/'这个字符是不会读进去的if(str == ".." && !stk.empty()){stk.pop();}else if(str != "." && !str.empty() && str != ".."){stk.push(str);}str.clear();}else{str.push_back(m);}}string result;if(stk.empty()) return "/";while(!stk.empty()){result = "/" + stk.top() + result;stk.pop();}return result;}
};

496. 下一个更大元素 I

这个题用递减数列,把小数据存进去找右边第一个大的数据,再把这个关系存进去(记得把栈顶出栈),我用hashmap进行关系建立,最后查结果,查不到就返回-1。

class Solution {public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {stack<int> num;vector<int> answer;map<int, int> s1;for(auto a:nums2){while(!num.empty() && num.top() < a){s1[num.top()] = a;num.pop();}num.push(a);}for(auto a:nums1){if(s1.count(a) == 0) answer.push_back(-1);else answer.push_back(s1[a]);}return answer;}
};

682. 棒球比赛

这个题也是给练手题,本来以为用asl码,但是俺也不知道棒球比赛能有60分?

class Solution {public:int calPoints(vector<string>& ops) {stack<int> num;int sum = 0;for(auto a:ops){if(a[0] == '+'){int t = num.top();num.pop();int t1 = t + num.top();num.push(t);num.push(t1);}else if(a[0] == 'D'){int t = num.top() + num.top();num.push(t);}else if(a[0] == 'C'){num.pop();}else num.push(stoi(a));//大家可以记一下这个函数}while(!num.empty()){sum += num.top();num.pop();}return sum;}
};

1021. 删除最外层的括号

我开始是寻找两个栈空之间的距离,把这两个之间的东西加起来,但是看了一下大佬的写的= =自愧不如,参考的力扣用户:ping-ze-ping-ze-ping-ping-ze的代码。

class Solution {public:string removeOuterParentheses(string S) {stack<char> a;string b("");for(int i = 0;i < S.length();i++){if(S[i] == ')') a.pop();if(!a.empty() ) b += S[i];if(S[i] == '(')  a.push(S[i]);}return b;}
}

341. 扁平化嵌套列表迭代器

难度中等题里面适合练手(俺开始没看懂题意,写的好烦啊)。

class NestedIterator {private:
stack<int> a;
stack<int> b;
void add(vector<NestedInteger> nested){for(auto nestedi : nested)if(nestedi.isInteger()) a.push(nestedi.getInteger());else add(nestedi.getList());
}
public:NestedIterator(vector<NestedInteger> &nestedList) {add(nestedList);while(!a.empty()){b.push(a.top());a.pop();}}int next() {int ai = b.top();b.pop();return ai;}bool hasNext() {return !b.empty();}
};

331. 验证二叉树的前序序列化

这是一棵二叉树 = =反正我的印象就是:空节点数=非空节点数 + 1,建议几个关于树的定理可以记一下。
然后#就是空,数就是非空,#比数多1个,那么如果是数就进栈,如果是#就出栈,那么当字符是#的时候而且#是字符串最后一位看栈是否为空,若为空那么就是验证成功,非空就是验证失败。
然后俺写出来就遇见两位的数字19这种,然后这是个string,难搞= =借鉴了一下别人的做法,他每次找到数,就往下找到下一个”,“数有很多”,“只有一个啊不得不说这个想法真厉害。

class Solution {private:
stack<char> a;
public:bool isValidSerialization(string preorder) {if (preorder.empty()) return false;for(int i = 0;i < preorder.length();i++){if(preorder[i] == '#'){if(a.empty()) return i == preorder.size() - 1;else {a.pop();i++;}}else{while (i < preorder.size() && preorder[i] != ',') i++;a.push(preorder[i]);}}return false;}
};

1081. 不同字符的最小子序列

这个问题原理很简单,就是一个单调栈(单调递增),如果栈内已经存在数据就吧这个数据给pass掉,如果数据比栈顶小,那么就删栈顶数据直到栈顶数据小于数据为止。因为C++的库函数实在感觉少,就用vector来代替,其实大家用go啊python啊可以直接调库。

class Solution {public:bool get_num(int i,string s,char si){for(int j = i + 1;j<s.length();j++) if(s[j] == si) return true;return false;}string smallestSubsequence(string s) {string str("");vector<char> already;int i = -1;for(auto si :s){i++;if(count(already.begin(),already.end(),si) > 0) continue;while(!already.empty() && already.back() > si && get_num(i,s,already.back()) == true) already.pop_back();already.push_back(si);}while(!already.empty()){str = already.back() + str;already.pop_back();}return str;}
};

C++算法学习(栈)相关推荐

  1. 数据结构与算法学习笔记——链栈

    数据结构与算法学习笔记(C语言) 链栈 在开始链栈的学习之前,我们先实现一下上一篇文章中提到的检查括号匹配的小程序,鉴于水平有限,本人就随便写一下代码好了,目标仅限于对功能的实现. /*用顺序栈这种数 ...

  2. 算法学习 (门徒计划)4-2 单调栈(Monotone-Stack)及经典问题 学习笔记

    算法学习 (门徒计划)4-2 单调栈(Monotone-Stack)及经典问题 学习笔记 前言 单调栈 基础 性质 代码实现 总结 经典例题 LeetCode 155. 最小栈 (基础) 解题思路 L ...

  3. 算法学习1:定容字符串栈的Java实现

    算法学习1:定容字符串栈的Java实现 代码 import java.io.File; import java.io.FileNotFoundException; import java.util.S ...

  4. 算法学习12: 单调队列和单调栈

    算法学习12: 单调队列和单调栈 单调队列 单调队列解决的问题: 窗口内最大/最小值的更新结构 单调队列的结构和操作 单调队列的应用 题目一: 生成窗口最大值数组[leetcode 239](http ...

  5. 原创 | 初学者友好!最全算法学习资源汇总(附链接)

    在计算机发展飞速的今天,也许有人会问,"今天计算机这么快,算法还重要吗?"其实永远不会有太快的计算机,因为我们总会想出新的应用.虽然在摩尔定律的作用下,计算机的计算能力每年都在飞快 ...

  6. 算法学习:强连通分量 --tarjan

    [定义] [强连通分量] 在一个子图中,任意点能够直接或者间接到达这个子图中的任意点,这个子图被称为强连通分量 [解决问题] 求图的强连通分量 同时能够起到 ...................缩点 ...

  7. 数据结构与算法学习笔记之 从0编号的数组

    数据结构与算法学习笔记之 从0编号的数组 前言 数组看似简单,但掌握精髓的却没有多少:他既是编程语言中的数据类型,又是最基础的数据结构: 一个小问题: 为什么数据要从0开始编号,而不是 从1开始呢? ...

  8. 七桥问题c语言程序数据结构,数据结构与算法学习——图论

    什么是图? 在计算机程序设计中,图结构也是一种非常常见的数据结构 但是图论其实是一个非常大的话题 图结构是一种与树结构有些相似的数据结构 图论是数学的一个分支,并且在数学概念上,树是图的一种 它以图为 ...

  9. fifo算法_【算法学习】分枝限界法

    分枝限界 关注那些不断已被他人成功应用的新思路.你的原创思想只应该应用在那些你正在研究的问题上. --托马斯·爱迪生(1847-1931) 这周到来的太快, 没想到这么快就迎来了考试. 干了这碗烤柿粥 ...

最新文章

  1. YOLOv4没交棒,但YOLOv5来了!
  2. 微信表白墙 微信小程序 吐槽墙 表白墙 java 开发
  3. 【廖雪峰python入门笔记】tuple_创建单元素
  4. modelsim-win64-10.1c的安装和基本使用
  5. IOS开发笔记17-Object-C中的继承
  6. 大神们,这是网易邮箱服务器的报错信息,能分析出来什么?
  7. 在表空间有足够free space的情况下出现ORA-1652
  8. OpenFileDialog对话框Filter属性
  9. Makefile中用宏定义进行条件编译(gcc -D)/在Makefile中进行宏定义-D
  10. Mysql之索引详解
  11. 安卓应用安全指南 4.6.1 处理文件 示例代码
  12. android按钮怎么事件监听,android 通过监听edittext实现button的点击事件
  13. PC电脑端QQ如何适应电脑端大小
  14. jquery. Validator验证框架ajax返回json数据
  15. 开课吧Java课堂:是什么TreeMap类
  16. 学习 trajectory.txt
  17. php_curl模拟登录有验证码实例
  18. pads铺铜不能开启drp_PADS2007 layout设置和基本操作步骤.ppt
  19. kylin 维度优化,Aggregation Group,Joint,Hierachy,Mandatory等解析
  20. Flutter 竖线 垂直分割线

热门文章

  1. APUE读书笔记-13守护进程(05)
  2. 关于三角函数图像的思考
  3. ubuntu 上 nvidia-smi 没显示所有的GPU
  4. Kotlin实现LeetCode算法题之String to Integer (atoi)
  5. 【软件project】之第五、六章总结
  6. Node聊天程序实例04:chat_ui.js
  7. cocos2dx 3.x Node::schedule
  8. Django视图系统
  9. Nginx 学习笔记(十)介绍HTTP / 2服务器推送(译)
  10. 从“连接”到“交互”—阿里巴巴智能对话交互实践及思考