JZ9 用两个栈实现队列
代码
void push(int node) {
stack1.push(node);
}
int pop() {
int res = -1;
if (stack2.empty()) {
//入队栈弹出 进入出队栈
if (stack1.empty()) {
return -1;
} else
while (!stack1.empty()) {
stack2.push(stack1.top());
stack1.pop();
}
}
res = stack2.top();
stack2.pop();
return res;
}
get
讲解视频
思路:
两个栈一个用作push,一个用作pop
入队——直接插入push栈,在栈顶
出队——
先判断pop栈有无元素可出。
pop栈空时,判断push栈有无元素,若无,两栈均无元素可用于弹出,即队空无法出队,返回-1;若push栈非空,将push栈中所有元素压入pop栈;
pop栈非空(本身非空,或判断后进行上述操作push栈有元素进入导致非空),弹出栈顶元素并返回。
JZ20包含min元素的栈
代码
//用于栈的push 与 pop
stack<int> s1;
//用于存储最小min
stack<int> s2;
void push(int value) {
s1.push(value);
//空或者新元素较小,则入栈
if (s2.empty() || s2.top() > value)
s2.push(value);
else
//重复加入栈顶
s2.push(s2.top());
}
void pop() {
s1.pop();
s2.pop();
}
int top() {
return s1.top();
}
int min() {
return s2.top();
}
};
get
s1保存栈中元素,s2为辅助栈,保存s1中从栈底截至各个元素,这一段元素中的最小元素。
入栈时压入s1,s2为空或者s2栈顶元素(即入栈前s1中的最小元素)更大,则表示新入栈的元素比s1之前的元素都要小,最小元素变化,新元素压入s2.
出栈时s1、2同步出栈
注意到判断条件s2.empty() || s2.top() > value不可修改顺序,否则会出错。
栈的压入、弹出序列
代码
bool IsPopOrder(vector<int> pushV, vector<int> popV) {
if (pushV.empty() || pushV.size() == 0) {
return true;
}
stack<int> s;
int iPush = 0;
int iPop = 0;
int lenPush = popV.size();
for (; iPush < lenPush; iPush++) {
s.push(pushV[iPush]);
while ((!s.empty()) && s.top() == popV[iPop]) {
iPop++;
s.pop();
}
}
int lenPop = popV.size();
for (; iPop < lenPop; iPop++) {
while ((!s.empty()) && s.top() == popV[iPop]) {
iPop++;
s.pop();
}
}
return s.empty();
}
get
压入序列,弹出序列,辅助栈
压入序列压入辅助栈。
比较栈顶与弹出序列的第一个弹出元素,若相同则弹出栈顶、弹出序列位序后移,继续比较当前栈顶和当前弹出元素。
若不同,压入序列压入辅助栈,继续上述操作。
可能存在压入序列全部入栈,而出栈序列未处理完的情况,再次使用一个for循环处理弹出序列,与辅助栈中元素进行比对,处理如上。
若比较完毕弹出序列后,辅助栈空,则表示按照入栈顺序入栈,按照弹出序列弹出,可将辅助栈中元素全部弹出,即辅助栈中元素按照弹出序列可完全弹出,则返回true
否则返回false
返回值由辅助栈是否为空决定。
反转单词序列
代码
string ReverseSentence(string str) {
int n=str.length();
reverse(str.begin(), str.end());
for(int i=0; i<n; i++){
int j=i;
while(j<n && str[j]!=' ')
j++;
reverse(str.begin()+i, str.begin()+j);
i=j;
}
return str;
}
get
单词拼写是正序,单词排序是逆序,各个单词之间用空格分开。
使用逆置函数reverse。
首先全部逆置,得到正确的单词顺序,但单词拼写是逆序的。
通过空格区分单词,单词内部拼写逆置。
滑动窗口的最大值
代码
vector<int> maxInWindows(const vector<int>& num, unsigned int size) {
vector<int> res ;
if (num.empty() || num.size() == 0 || size == 0 || num.size() < size) {
return res;
}
for (int i = 0; i <= num.size() - size; i++) {
int cur=0;
for (int j = i; j < i+size; j++) {
cur = max(num[j], cur);
}
res.push_back(cur);
}
return res;
}
get
暴力解法
先处理需要返回空的情况
找滑动窗口中的最大值,i确定滑动窗口的起点,j为滑动窗口中正在处理的最后位置,cur为i~j中的最大元素。滑动窗口中所有的处理完后,cur归入结果。