第一题
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
class MinStack {
private:
stack<int> s;
stack<int> min_s;
public:
void push(int x) {
s.push(x);
if(min_s.empty())
{
min_s.push(x);
return;
}
if(min_s.top()>=x)//一定要大于等于,不然多个相同的最小值会出问题
{
min_s.push(x);
}
}
void pop() {
if(s.top()==min_s.top())
{
min_s.pop();
}
s.pop();
}
int top() {
return s.top();
}
int min() {
return min_s.top();
}
};
其实这里也可以不通过辅助栈来解决这个问题
只需要记录当前值与最小值之间差值和最小值
差值大于0,说明当前值不为最小值,不需要更新最小值
差值小于0,说明当前值是最小值,删除的时候我们需要更新最小值
数据溢出的问题
class MinStack {
private:
stack<long long> s;
long long Min;
public:
void push(int x) {
if (s.empty()) //初始化差值为0
{
s.push(0);
Min = x;
return;
}
s.push((long long)x - Min);//先算差值,再更新Min。
if (x < Min)
{
Min = x;
}
}
void pop() {
if (s.top() >= 0)
{
s.pop();
}
else
{
Min -= s.top();
s.pop();
}
}
int top() {
if(s.top()>=0)
{
return Min+s.top();
}
else
{
return Min;
}
}
int min()
{
return Min;
}
};
第二题
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int> s;
while(head!=nullptr)
{
s.push(head->val);
head=head->next;
}
vector<int> ret;
while(!s.empty())
{
ret.push_back(s.top());
s.pop();
}
return ret;
}
};
第三题
给定一个整数数组 asteroids,表示在同一行的小行星。
对于数组中的每一个元素,其绝对值表示小行星的大小,正负表示小行星的移动方向(正表示向右移动,负表示向左移动)。每一颗小行星以相同的速度移动。
找出碰撞后剩下的所有小行星。碰撞规则:两个行星相互碰撞,较小的行星会爆炸。如果两颗行星大小相同,则两颗行星都会爆炸。两颗移动方向相同的行星,永远不会发生碰撞。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/XagZNi
class Solution {
public:
//先找到第一个向右的星星,右行撞完,再继续找
vector<int> asteroidCollision(vector<int>& asteroids) {
vector<int> ret_aster; //用顺序表也能实现栈的操作
bool alive=true;
for(auto e:asteroids)
{
alive=true;
//如果栈顶的星星向右并且遇到了向左的星星,那么相撞
while(alive&&e < 0 && !ret_aster.empty() && ret_aster.back() > 0){
if(ret_aster.back()>(-e)){
alive=false;
}
else if(ret_aster.back()==(-e)) {
alive=false;
ret_aster.pop_back();
}
else{
ret_aster.pop_back();
}
}
if(alive)
{
ret_aster.push_back(e);
}
}
return ret_aster;
}
};