Leetcode 剑指 Offer 09. 用两个栈实现队列
题目
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
两个栈实现队列,首先明确栈和队列的区别,栈是 FILO 即先进后出,队列是 FIFO 即先进先出;然后假设两个栈 s1 和 s2,s1 用于读取输入数据,可知 s1 读取数据后再读出为倒序(比如,1、2、3读入,3、2、1读出),这时再用 s2 来接收 s1 读出的数据,接收之后再从 s2 读出数据,这时数据为 s1 内的倒序,即原数据倒序的倒序——正序。现在明确了如何用两个栈模拟队列,那么核心问题就在于实现题目中的两个函数,尾部插入和头部删除;尾部插入部分先暂时将新插入的整数存入 s1 将 s1 作为第一个栈,将 s2 作为模拟队列的栈,由于不能插入一个数就立即将 s1 中的数据传入 s2(如果这样那就和直接传入 s2 没有区别),故用 s1 保存目前插入的整数,当执行删除头部函数时则必须要使用 s2, 此时将 s1 中的数据倒入 s2 。上面说的可能比较乱套,大概就是插入数据的时候只使用栈 s1,当进行删除头部操作时由于 s1 不能单独满足队列的特性,需要将数据传入 s2 ,以下为代码:
// 注意 stack不可遍历
stack<int> s1, s2;
CQueue() {
}
void appendTail(int value) {
s1.push(value);
}
int deleteHead() {
int res;
if(s1.size() <= 0 && s2.size() <= 0){
return -1;
}
//将s1倒入s2
if(s2.size() <= 0){
while(s1.size() > 0){
s2.push(s1.top());
s1.pop();
}
}
res = s2.top();
s2.pop();
return res;
}
总体来说本题较为基础,只是考察了栈和队列的特性。
Leetcode 20. 有效的括号
题目
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
创建一个栈,保存左半边括号,当读到右半边括号就判断是否匹配,最后判断栈内是否有剩余左括号。(代码没优化,我是真不懂为啥三个月之前居然没做出来)
bool isValid(string s) {
stack<char> temp;
for(int i = 0; i < s.size(); i++){
if(s[i] == '(' || s[i] == '[' || s[i] == '{'){
temp.push(s[i]);
}else if(!temp.empty() && temp.top() == '(' && s[i] == ')'){
temp.pop();
}else if(!temp.empty() && temp.top() == '[' && s[i] == ']'){
temp.pop();
}else if(!temp.empty() && temp.top() == '{' && s[i] == '}'){
temp.pop();
}else{
return false;
}
}
if(temp.empty()){
return true;
}
return false;
}