微软面试百题002——返回优先级的栈
来源:互联网 发布:linux认证工程师 编辑:程序博客网 时间:2024/06/05 07:22
微软面试百题002——看上去貌似很简单实则暗藏杀机 优先栈
1.问题描述:
设计一个栈,添加min函数,可以让我们在O(1)时间复杂度内完成push,pop以及min操作(min操作返回栈内权值最小的元素)
首先我们先来复习一下栈这个数据结构的性质:
栈作为一种先进先出的数据结构,pop出去的一定是刚刚才push进来的元素
但是本题中又牵扯到了min函数,又让我们感觉到了一丝一丝的优先队列的感觉
2.思维发展导图
1.首先刚开始想到既然是优先化一个栈的话,我已开始是这么考虑的,近顺序的存储结构很难来进行min的操作,可不可以采用链栈的方式呢
我是这么考虑的,链栈的话我们只需要额外开辟一个节点指向最小的元素节点就可以了,这不就轻松搞定了吗
显然这么做少考虑了一点,如果最小的成为栈顶的话,没有保存倒数第二小节点地址的我们就绝对会出错,导致我们之后的min的跟踪失败,而要是依旧采用链栈的话,我们为了解决这个问题就必须要开辟大量的节点保存最小信息,反而将问题复杂化了
2.再次开辟一个内存空间,实现的内容是反向优先队列,用来保存递减的顺序
在这里可能就有人会问难道不会出现和上面一样的错误码,实际上我们可以证明,是不会出现那样的错误的,因为这个优先队列始终是保持递减有序的,我们pop的时候如果遇到在优先队列中的元素的话,同步pop,否则优先队列不变,这样做的话,一个优先队列中的节点如果存在一个比他先出现的且比他大的元素是一定在优先队列中比他更靠前的位置中的
3.动态规划的应用:这个是参考了大神的笔记后发现还可以采用动态规划的思想,虽然一样占用了和第二种方法一样大的内存空间,但是这样子做的话就少了对另一种数据结构的维护,并且动态规划的思想也是非常的而优秀的
我们对于每一个节点不仅开辟内存保留原本应该保留的键值,我们还开辟内存保存该节点之前的栈的元素的最小值,那么根据动态规划的原理,我们只需要维护当前的节点就好
3.代码实现:(C++类封装)
3.1动态规划的思想:
#include"iostream"#include"cstdio"#include"cstdlib"#define N 100using namespace std;template<typename T>struct node{T key;T min;};template<typename T>class prestack{public:prestack(){memset(content,0,sizeof(content));top=0;} void push(T);T pop();T min();private:struct node<T> content[N];int top;};template<typename T>void prestack<T>::push(T p){if(top==0) {content[++top].key=p;content[1].min=p;}else //动态规划的思想{if(p<content[top].min) content[++top].min=p;else content[++top].min=content[top-1].min;content[top].key=p;}}template<typename T>T prestack<T>::pop() //小心prestack神明的时候必须要加<T>{return content[top--].key;}template<typename T>T prestack<T>::min(){return content[top].min;}int main(){prestack<int> my;my.push(-2);my.push(5);my.push(9);my.push(4);my.push(6);my.push(8);my.push(-4);my.push(-2);cout<<my.min()<<endl;cout<<my.pop()<<endl;cout<<my.pop()<<endl;cout<<my.min()<<endl;return 0;} //输出结果是-4,-2,-4,-2,结果正确
3.2优先队列+栈实现
#include"iostream"#include"cstdlib"#include"cstring"#define N 100using namespace std;template<typename T>class prestack{public:prestack(){memset(data,0,sizeof(data));memset(heap,0,sizeof(heap));top=heapnum=0;}void push(T);T pop();T min();private:T data[N];T heap[N];int top;int heapnum;};template<typename T>void prestack<T>::push(T p){data[++top]=p;if(p<heap[heapnum]) heap[++heapnum]=p;}template<typename T>T prestack<T>::pop(){T help;help=data[top--];if(help==heap[heapnum]) heapnum--;return help;}template<typename T>T prestack<T>::min(){return heap[heapnum];}int main(){prestack<int> my;my.push(-2);my.push(5);my.push(9);my.push(4);my.push(6);my.push(8);my.push(-4);my.push(-2);cout<<my.min()<<endl;cout<<my.pop()<<endl;cout<<my.pop()<<endl;cout<<my.min()<<endl;return 0;}
4.疑惑点:
1.为什么C++中结构体模板不能对typedef进行作用,很是奇怪,特定语法吗?时为什么要提出这种语法结构的呢
2.当要再追加问题:请在O(1)时间内min还可以返回出该最小元素在栈内的位置的时候,除了再开辟一内存保存地址之外,还有什么更好的方法吗
1 0
- 微软面试百题002——返回优先级的栈
- 一道微软面试的智力测验题——王志峰(摘自《微软360度》)
- 微软面试百题006——八皇后变种
- 微软面试百题007——链表相交
- 微软面试百题011——找数
- 微软面试100题—自做
- 微软面试百题005——堆实现求前k大/小的数
- 微软面试百题012——5050的各种限制解法
- 微软面试的急智题
- microsoft微软——面试
- 一道微软面试的智力测验题——王志峰(摘自《微软360度》) - microsoft360的专栏 - CSDNBlog
- [微软面试100题] 设计包含min函数的栈
- 微软面试100题-栈的push-pop序列问题
- 微软不同分工不同侧重的面试——开发工程师的面试(摘自《微软360度》)
- 微软不同分工不同侧重的面试——测试人员的面试(摘自《微软360度》)
- 微软不同分工不同侧重的面试——项目经理的面试(摘自《微软60度》)
- 微软不同分工不同侧重的面试——开发工程师的面试(摘自《微软360度》)
- 微软面试100题——第一题
- 信号量 Semaphore
- TestNG中的组groups概念
- 简易加密工具类
- 关于扩展欧几里得算法的一些资料
- nand flash驱动的编写
- 微软面试百题002——返回优先级的栈
- 文章标题
- Java Exception 捕获和展示
- hdu 2841 Visible Trees 容斥,分解质因数
- SharedPreferences存储
- Three.js学习笔记---我和小伙伴都惊呆了
- PHP位运算符详解
- 向量基础知识
- HDU 5800 To My Girlfriend (动态规划)