今天的内容不算太难,前两道题对基本功还是有要求的,第一题看了视频以后才弄明白,做完了第一道,第二道顺理成章就能做出来了,第三题之前做过,很简单,第四题我把代码写复杂了,看完讲解视频以后把代码优化了一下。
232.用栈实现队列
这里要用两个栈来实现队列,我觉得其中一个易错点就是执行pop()函数的时候需要把stack_in的所有元素放入stack_out中,将stack_out的栈顶元素弹出以后却不需要将stack_out的元素再放回stack_in中,这是因为后面的peek函数调用pop()再重新push时,如果stack_out的元素已经放回stack_in,那么元素顺序就会出错。
其他的都不难理解。
这是我的代码
class MyQueue {
public:
MyQueue() {
this -> stack_in = new stack<int>();
this -> stack_out = new stack<int>();
}
void push(int x) {
this -> stack_in -> push(x);
}
int pop() {
if(this -> stack_out -> empty()){
//先将stack_in的数据存入stack_out中,再对stack_out弹出栈顶操作
while(!this -> stack_in -> empty()){
this -> stack_out -> push(stack_in -> top()); //stack_out入栈
this -> stack_in -> pop(); //stack_in出栈
}
}
int result = this -> stack_out -> top();
this -> stack_out -> pop();
return result;
}
int peek() {
int result = this -> pop();
this -> stack_out -> push(result);
return result;
}
bool empty() {
return this -> stack_in -> empty() && this -> stack_out -> empty();
}
private:
stack<int>* stack_in;
stack<int>* stack_out;
};
225. 用队列实现栈
这道题只需要用一个队列就行了,没有看讲解视频,自己琢磨出来的,出栈就用队列的循环出队+入队实现。
class MyStack {
public:
MyStack() {
this -> My_Queue = new queue<int>();
}
void push(int x) {
this -> My_Queue -> push(x);
}
int pop() {
int count = 0;
while(count < this -> My_Queue -> size() - 1){
int temp = this -> My_Queue -> front(); //获取队首元素
this -> My_Queue -> pop();
this -> My_Queue -> push(temp);
count++;
}
int result = this -> My_Queue -> front();
this -> My_Queue -> pop();
return result;
}
int top() {
int top = this -> pop();
this -> push(top);
return top;
}
bool empty() {
return this -> My_Queue -> empty();
}
private:
queue<int>* My_Queue;
};
20. 有效的括号
这道题目之前做过,思路很简单,没什么好说的。但是今天做的程序耗时居然不如上次,思路都是一样的,我就贴上次的代码吧。
class Solution {
public:
bool isValid(string s) {
std::stack<char> charStack;
for(char c:s){
if(c == '(' || c == '[' || c == '{') //左边的括号应当入栈
charStack.push(c);
else { //右边的括号,应当出栈
if(charStack.empty()) //栈内没有元素了
return false;
else{ //栈内还有元素
if(reverse(c) == charStack.top()) //括号匹配正确
charStack.pop();
else
return false;
}
}
}
if(charStack.empty())
return true;
return false;
}
char reverse(char a){
switch(a){
case ')' : return '(';break;
case ']' : return '[';break;
case '}' : return '{';break;
default : return 'a';
}
}
};
1047. 删除字符串中的所有相邻重复项
这道题我还是太老实了。。老老实实用两个栈来做,结果代码写的很复杂,虽然AC了但是程序耗时太久了,看完讲解视频以后发现思路都是一样的,只是卡尔直接用字符串来模拟栈,后面就不需要将栈内的元素转化为字符串这一步骤,节约了时间和空间,感觉被自己蠢哭了。
这是优化前的代码
class Solution {
public:
string removeDuplicates(string s) {
string result = "";
stack<char> My_Stack_left;
stack<char> My_Stack_right;
for(char c : s)
My_Stack_right.push(c);
while(!My_Stack_right.empty()){
My_Stack_left.push(My_Stack_right.top());
My_Stack_right.pop();
while(!My_Stack_right.empty() && !My_Stack_left.empty() && My_Stack_left.top() == My_Stack_right.top()){
My_Stack_left.pop();
My_Stack_right.pop();
}
}
while(!My_Stack_left.empty()){
result += My_Stack_left.top();
My_Stack_left.pop();
}
return result;
}
};
这是优化后的代码
class Solution {
public:
string removeDuplicates(string s) {
string result = "";
for(char c : s){
if(result == "" || result[result.size() - 1] != c)
result += c;
else result.resize(result.size() - 1);
}
return result;
}
};
无语。。。。看来以后用某种数据结构解决问题不一定非要用这个数据结构,借鉴其思想就可以了。血淋淋的教训。。。