使用两个栈实现队列
思路:元素进栈以后,只能优先弹出末尾元素,但是队列每次弹出的却是最先进入的元素,如果能够将栈中元素全部取出来,才能访问到最前面的元素,此时,可以用另一个栈来辅助取出。
class solution
{
public:
//入队列就正常入栈
void push(int node)
{
stack1.push(node);
}
int pop()
{
//将第一个栈中内容弹出放入第二个栈中
while(!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
//第二个栈栈顶就是最先进来的元素,即队首
int res = stack2.top();//获取栈顶元素
stack2.pop();//移除栈顶
//再将第二个栈的剩余元素放回第一个栈
while(!stack2.empty())
{
stack1.push(stack2.top());
stack2.pop();
}
return res;
}
private:
stack<int> stack1;//堆栈模板
stack<int> stack2;
};
使用两个队列实现栈
思路:队列只能进行队首出,队尾进,先进先出,而栈先进后出
则将队列的前n-1个元素弹出放入第二个队列,剩余的最后一个元素弹出输出即可实现栈
class mystack
{
public:
void push(int data)
{
q1.push(data);
}
int pop()
{
//将第一个队列前n-1个数据放入第二个队列
if(q1.empty())
{
return 0;
}else if(q1.size() == 1)
{
int res = q1.front();
q1.pop();
return res;
}
int s = q1.size();
for(int i = 0; i<s-1;i++)
{
//将第一个队列的首元素放入第二个队列队尾
q2.push(q1.front());
q1.pop();
}
//第一个队列的最后一个元素输出
int res = q1.front();
//将第二个队列的元素放入第一个队列
while(!q2.empty())
{
q1.push(q2.front());
q2.pop();
}
return res;
}
private:
queue<int> q1;//队列模板
queue<int> q2;
};
有效括弧序列
给出一个仅包含字符‘(’,‘)’,‘{’,‘}’,‘[’,']'的字符串,判断给出的字符串是否是合法的括号序列,括号必须以正确的顺序关闭,”()“和”(){}[]“都是合法的括号序列,但"(]“和”([)]"不合法
要求:空间复杂度O(n),时间复杂度O(n)
思路:
遍历字符串,遇到’(‘’{‘’[’ 系列的括号,将对应的’)‘’}‘’]'元素入栈,若遇到与栈顶元素(右括号系列)相同,则栈顶出栈,遍历完为空则为有效括弧。
//有效括弧序列
class bracket
{
public:
bool isVaild(string s)
{
//借助栈来判断
stack<char> temp;
int len = s.length();
//遍历字符串
for(int i = 0; i < len; i++)
{
//'['与']'之间相差2,'('与')'之间相差1,'{'与'}'之间相差2
if(temp.empty()||(s[i]-1 != temp.top()&&s[i]-2 != temp.top()))
temp.push(s[i]);
else
temp.pop();
}
//为空是有效括弧,不为空为无效
return temp.empty();
}
};
求最小的k个数
给定一个长度为n的可能有重复值的数组,找出其中不去重的最小的k个数。
例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字为1,2,3,4
要求:空间复杂度O(n),时间复杂度O(nlogn)
思路:排序,截取
//求最小的k个数
class solution1
{
public:
vector<int> get_top_k(vector<int> &va,int k)
{
vector<int> res;
if (k == 0 || k > input.size()) return res;
priority_queue<int> pq;//优先队列
for (int i = 0; i < input.size(); ++i) {
if (pq.size() < k) pq.push(input[i]);
else if (input[i] < pq.top()) {
pq.pop();
pq.push(input[i]);
}
}
while (!pq.empty()) {
res.push_back(pq.top());
pq.pop();
}
return res;
}
};
求数据流的中位数
//求数据流中的中位数
class solution2
{
public:
public:
void Insert(int num) {
// 时间复杂度O(logN),空间复杂度O(N)
if (maxHeap.empty() || num < maxHeap.top()) maxHeap.push(num);
else minHeap.push(num);
if (maxHeap.size() > minHeap.size() + 1) {
minHeap.push(maxHeap.top());
maxHeap.pop();
} else if (minHeap.size() > maxHeap.size() + 1) {
maxHeap.push(minHeap.top());
minHeap.pop();
}
}
double GetMedian() {
// 时间复杂度O(1),空间复杂度O(1)
if (maxHeap.size() > minHeap.size()) return maxHeap.top();
else if (maxHeap.size() < minHeap.size()) return minHeap.top();
else return (maxHeap.top() + minHeap.top()) / 2.0;
}
private:
priority_queue<int, vector<int>, less<int>> maxHeap;
priority_queue<int, vector<int>, greater<int>> minHeap;
};
表达式求值
思路:
一.处理运算符优先级的问题。
把减号看成加一个数的相反数,则表达式只有乘除加,乘除的优先级高,则可把加减前后的数放入栈中,遇到乘除把前后俩个数乘除后的结果入栈,最后把存的数字全部相加即可。
二.处理括号问题
可把括号中的部分看成一个新的表达式,可将新的表达式递归求解,得到一个数字,再运算.
具体步骤:
1.使用栈辅助处理优先级,默认符号位加号。
2.遍历字符串,遇到数字,则将连续的数字字符部分转化为int型数字。
3.遇到左括号,则将括号后的部分送入递归,处理子问题,遇到右括号代表已经达到这个子问题的结尾,结束继续遍历字符串,将子问题的加法部分相加为一个数字返回。
4.当遇到符号的时候如果是+,得到的数字正常入栈,如果是-,将其相反数入栈,如果是*/,则将栈中内容弹出与后一个元素相乘/除再入栈。
5.最后将栈中剩余的所有元素,进行一次全部相加。
//表达式求值
class solution3
{
public :
vector<int> function(string s, int index)
{
//定义辅助栈
stack<int> stack;
int num = 0;
//默认运算符为+
char op = '+';
int i;
for(i = index; i < s.length();i++)
{
//数字转化为int数字
if(isdigit(s[i]))
{
num = num * 10 +s[i]-'0';
if(i!=s.length()-1)
{
continue;
}
}
//碰到'('时,把整个括号内的当成一个数字处理
if(s[i] == '(')
{
//递归处理括号
vector<int> res = function(s,i+1);
num = res[0];
i = res[1];
if(i!=s.length()-1)
continue;
}
int temp = 0;
switch(op)
{
//加减号先入栈
case '+':
stack.push(num);
break;
case '-':
//相反数
stack.push(-num);
break;
case '*':
temp = stack.top();
stack.pop();
stack.push(temp*num);
break;
case '/':
temp = stack.top();
stack.pop();
stack.push(temp/num);
break;
}
num = 0;
//右括号结束递归
if(s[i] == ')')
{
break;
}
else
{
op = s[i];
}
}
int sum = 0;
//栈中元素相加
while(!stack.empty())
{
sum+=stack.top();
stack.pop();
}
//将sum和i返回
vector<int> a;
a.push_back(sum);
a.push_back(i);
return a;
}
int solve(string s)
{
return function(s,0)[0];
}
};