文章内容为LeetCode刷题笔记,如发现错误请多多指教
17、包含min函数的栈:栈的规则性设计
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
对于这个问题,我们可以采取用一个辅助栈的方法来解决,这个辅助栈栈头元素永远是数据的最小值,当需要最小值时返回辅助栈的栈头即可
class MinStack {
public:
/** initialize your data structure here. */
stack<int> data_stack;//数据栈
stack<int> min_stack;//辅助栈
MinStack() {
}
void push(int x) {
data_stack.push(x);//数据进来,数据栈必须压栈
//辅助栈如果为空或者辅助栈头大于数据,就把数据压栈
if(min_stack.size()==0||min_stack.top()>x){
min_stack.push(x);
}
//否则把辅助栈头元素再次压栈,这样保证辅助栈的头元素一定是最小的
else{
min_stack.push(min_stack.top());
}
}
void pop() {
if(data_stack.size()==0) return;
data_stack.pop();
min_stack.pop();
}
int top() {
return data_stack.top();
}
int min() {
return min_stack.top();
}
};
18、栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列
解题思路:
1、要判定第二个序列是否可能是该栈的弹出序列,就要使用指定的入栈顺序
2、模拟出来对应的弹栈序列,我们设入栈顺序序列式pushV, 可能出栈序列popV
3、popv的第一个元素,一定是后入栈,先弹栈的,而我们的入栈顺序是一定的
4、也就决定了,我们必须一直入栈,直到碰到popv的第一个元素,然后开始弹栈
5、后在循环这个过程,如果符合要求,后栈结构一定是空的
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
if(pushed.size()!=popped.size()){//如果两个数组大小不一样,那么直接错
return false;
}
//该题默认两个空数组返回true
if(pushed.size()==0&&popped.size()==0){
return true;
}
stack<int> st;
int i=0,j=0;
for(;i<pushed.size();i++){
st.push(pushed[i]);
while(!st.empty()&&st.top()==popped[j]){
st.pop();
j++;
}
}
return st.empty();
}
};
19、二叉树层序遍历
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回:
[3,9,20,15,7]
可以使用一个队列来实现二叉树的层序遍历
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
//如果根指针为空,则返回一个空数组
if(root==nullptr){
return vector<int>();
}
vector<int> v;//建立一个数组存储数据
queue<TreeNode*> q;//建立一个指针队列进行辅助
q.push(root);//先将根指针压入队列
while(!q.empty()){
//如果队列不为空,就新建一个指针等于队列头指针
TreeNode *father=q.front();
q.pop();
v.push_back(father->val);
if(father->left!=nullptr){
q.push(father->left);
}
if(father->right!=nullptr){
q.push(father->right);
}
}
return v;
}
};