1:设计一个有getMin功能的栈
class MinStack {
public:
//stackData.top()只会大于或等于stackMin.top()的值
stack<int>stackData;
stack<int>stackMin;
MinStack() {}
void push(int x) {
stackData.push(x);//栈空或者x<=stackMin.top()
if(stackMin.size() == 0 || x <= stackMin.top())
stackMin.push(x);
}
void pop() {
//出栈时需要同步
int val=stackData.top();
stackData.pop();
if(val==stackMin.top())
stackMin.pop();
}
int top() {
if(!stackData.empty())
return stackData.top();
else
return -1;
}
int min() {
return stackMin.empty()?-1:stackMin.top();
}
};
2:由两个栈组成的队列
class CQueue {
public:
//A用来入栈,B用来出栈
// 出栈时B中若有元素则依次弹出,否则就将A中全部转移到B中再弹出
stack<int>A;
stack<int>B;
CQueue() {}
void appendTail(int value) {
A.push(value);
}
int deleteHead() {
if(B.empty()){
while (!A.empty()){
B.push(A.top());
A.pop();
}
}
if(B.empty())
return -1;//两栈空空
else{
int val=B.top();
B.pop();
return val;
}
}
};
3:如何仅用递归函数和栈操作逆序一个栈?
class Solution{
public:
int getAndRemoveLastElement(stack<int>&stack){
int result=stack.top();
stack.pop();
if(stack.empty())
return result;
else{
int last=getAndRemoveLastElement(stack);
stack.push(result);
return last;
}
}
};
4:用一个栈实现另一个栈的排序问题
class Solution{
public:
void sortStackByStack(stack<int>&S){
stack<int>help;//辅助栈,元素从顶往下升序排列
while (!S.empty()){
int cur=S.top();
S.pop();
//每次加入help中的元素为当前最小值
while (!help.empty() && help.top() < cur){
S.push(help.top());
help.pop();
}
help.push(cur);
}
//挪回S中
while (!help.empty()){
S.push(help.top());
help.pop();
}
}
};
5:用栈来求解汉诺塔问题
class Solution{
public:
//函数调用Solution.hanoi(N,A,B,C);将N个盘子从A移动到C
void hanoi(int N ,char source , char relay ,char destination){
if(N == 1)
cout << source << "-->" << destination << endl ;
else
{
//N>=2时,将(N-1)个从A移动到B,借助C;再将N-1从B移动到C,借助A
hanoi(N-1 , source , destination , relay) ;
cout << source << "-->" << destination << endl ;
hanoi(N-1 , relay , source , destination) ;
}
}
};
6:生成窗口最大值问题
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res; //用来存结果的vector
deque<int> temp; //双端队列
for(int i=0; i<nums.size(); ++i){
while(!temp.empty() && nums[i] > nums[temp.back()]){
//while这步操作是为了让当前窗口最大值的索引值放到temp的队头
temp.pop_back();
}
//这里的if判断条件中的第二个是为了判断队头是否过期,也就是说队头的索引是否小于当前索引
if(!temp.empty() && temp.front() < i - k + 1) temp.pop_front();
temp.push_back(i);
if(i>=k-1) res.push_back(nums[temp.front()]);
}
return res;
}
};
7:最大值减去最小值小于或等于num的子数组数量
链接:https://www.nowcoder.com/questionTerminal/5fe02eb175974e18b9a546812a17428e
来源:牛客网
int getNum(vector<int>& arr, int num)
{
int n = arr.size();
deque<int> qmin, qmax;
int i=0, j=0, res=0;
while(i<n) {
while(j<n) {
while(!qmin.empty() && arr[qmin.back()]>=arr[j]) {
qmin.pop_back();
}
qmin.push_back(j);
while(!qmax.empty() && arr[qmax.back()]<=arr[j])
{
qmax.pop_back();
}
qmax.push_back(j);
if(arr[qmax.front()] - arr[qmin.front()] > num) break;
j++;
}
if(qmin.front()==i) qmin.pop_front();
if(qmax.front()==i) qmax.pop_front();
res += j - i;
i++;
}
return res;
}
8:求最大子矩阵的大小
class Solution
{
public:
int maximalRectangle(vector<vector<int>>& matrix)
{
if(matrix.empty())
{
return 0;
}
int maxArea = 0;
vector<int> height(matrix[0].size(), 0);
for(int i=0; i<matrix.size(); ++i)
{
for(int j=0; j<matrix[0].size(); ++j)
{
height[j] = (matrix[i][j] == 0) ? 0 : height[j] + 1;
}
maxArea = (maxRecFromBottom(height) > maxArea) ? maxRecFromBottom(height) : maxArea;
}
return maxArea;
}
int maxRecFromBottom(vector<int> height)
{
if(height.size() == 0)
{
return 0;
}
int maxArea = 0;
stack<int> stack1;
for(int i=0; i<height.size(); ++i)
{
while(!stack1.empty() && height[i] <= height[stack1.top()])
{
int j = stack1.top();
stack1.pop();
int k = stack1.empty() ? -1 : stack1.top();
int curArea = (i - k - 1) * height[j];
maxArea = (maxArea > curArea) ? maxArea : curArea;
}
stack1.push(i);
}
while(!stack1.empty())
{
int j = stack1.top();
stack1.pop();
int k = stack1.empty() ? -1 : stack1.top();
int curArea = (height.size() - k - 1) * height[j];
maxArea = (maxArea > curArea) ? maxArea : curArea;
}
return maxArea;
}
};