之前收藏了极客时间的算法训练营3期 共10周,计划每周内容分3p博客来记录学习,主要形式为
方法类型1
题1
题解
题2
题解
方法类型2
题1
题解
……
题目大体来自leetcode 和 acwing
主要记录和理解代码,所以基本完全搬运了视频题解代码,
个人学习感受体现在大致思路的总结和注释上。
栈
class Solution {
public:
bool isValid(string s) {
for(char ch : s){
if (ch == '(' || ch == '[' || ch == '{') s1.push(ch);//这三种情况会入栈
else{//遇到不是左括号的情况返回false的情况更好讨论。
if (s1.empty()) return false;
if (ch == '}' && s1.top() != '{') return false;
if (ch == ']' && s1.top() != '[') return false;
if (ch == ')' && s1.top() != '(') return false;
s1.pop();
}
}
return s1.empty();//空了就对了,还有说明false;
}
private:
stack<char> s1;//第一次定义成了s,命名重复了;
};
直接调用了库来实现。
class MinStack {
public:
MinStack() {
}
void push(int val) {
s.push(val);//为了出栈方便,所以每个值都会计算之前的最小值入栈
if (preMin.empty()) preMin.push(val);
else preMin.push(min(preMin.top(), val));
}
void pop() {
s.pop();//两个栈一样高;
preMin.pop();
}
int top() {
return s.top();
}
int getMin() {
return preMin.top();
}
private:
stack<int> s;
stack<int> preMin;
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
class Solution {
public:
int evalRPN(vector<string>& tokens) {
for(string& token : tokens){
if (token == "+" || token == "-" || token == "*" || token == "/"){
int y = s.top();//先出来的是第二个计算值
s.pop();
int x = s.top();
s.pop();
int z = calc(x, y, token);
s.push(z);//两个数字变一个入栈
}else{
s.push(atoi(token.c_str()));//不是符号数字入栈
}
}
return s.top();
}
private:
stack<int> s;
int calc (int x, int y, string& op){
if(op == "+") return x + y;
if(op == "-") return x - y;
if(op == "*") return x * y;
if(op == "/") return x / y;
return 0;
}
};
class Solution {
public:
int calculate(string s) {
s += ' ';//高效解决结尾数字无法判断的问题
vector<string> tokens;
string number = "";
for(char ch : s){
if(ch >= '0' && ch <= '9'){
number += ch;//重载的+=,插入了字符到字符串中
continue;
}else{
if(!number.empty()){//把字符串整个加入到vector里
tokens.push_back(number);
number = "";
}
}
if(ch == ' ') continue;
int currRank = getRank(ch);//判定当前符号的优先级
while(!ops.empty() && currRank <= getRank(ops.top())){
tokens.push_back(string(1, ops.top()));
ops.pop();//符号栈顶优先级高时,先出符号栈进入vector
}
ops.push(ch);//出完了把当前符号入栈
}
while(!ops.empty()){//最后把所有符号栈剩余内容放到表达式里
tokens.push_back(string(1,ops.top()));
ops.pop();
}
return evalRPN(tokens);//逆波兰表达式求值
}
private:
int evalRPN(vector<string>& tokens) {//逆波兰表达式求值
for (string& token : tokens) {
if (token == "+" || token == "-" || token == "*" || token == "/") {
int y = s.top();
s.pop();
int x = s.top();
s.pop();
int z = calc(x, y, token);
s.push(z);
}
else {
s.push(atoi(token.c_str()));
}
}
return s.top();
}
stack<int> s;
int calc(int x, int y, string& op) {
if (op == "+") return x + y;
if (op == "-") return x - y;
if (op == "*") return x * y;
if (op == "/") return x / y;
return 0;
}
stack<char> ops;
int getRank(char op){
if(op == '+' || op == '-') return 1;
if(op == '*' || op == '/') return 2;
return 0;
}
};
这里有类似 -3 +2的算式,可以用补0的方式,补成0-3+2
本题教学了根据不同情况补0的方式
class Solution {
public:
int calculate(string s) {
s += ' ';
vector<string> token;//逆波兰表达式
string number = "";
bool needZero = true;//没有说明存在-当做负号,可
//以在诸如-3 + 3这类算式前加0
for(char ch : s){//大体同224题
if(ch >= '0' && ch <= '9'){
number += ch;
needZero = false;//数字打头不用补0
continue;
}else{
if(!number.empty()){
token.push_back(number);
number = "";
}
}
if (ch == ' ') continue;
if (ch == '(') {
ops.push(ch);
needZero = true;
continue;//左括号直接入栈标记括号所在位置
}
if (ch == ')'){//遇到右括号,左括号之前的所有值计算
while(ops.top() != '('){
token.push_back(string(1,ops.top()));
ops.pop();
}
ops.pop();//弹出左括号
needZero = false;//右括号完成后肯定会入栈一个值,不用补0
continue;
}
if(needZero == true && (ch == '-')){
token.push_back("0");//减号不清楚是否是负号需要考虑补0
}
int currRank = getRank(ch);
while(!ops.empty() && currRank <= getRank(ops.top())){
token.push_back(string(1,ops.top()));
ops.pop();
}
needZero = true;//计算完一串式子,新的表达式部分需要补0
//也许有这种算式? 2 * 3 + 1 + -1
ops.push(ch);
}
while (!ops.empty()){
token.push_back(string(1,ops.top()));
ops.pop();
}
return evalRPN(token);
}
private:
stack<char> ops;
stack<int> num;
int evalRPN(vector<string>& tokens){
for(string& token : tokens){
if(token == "+" || token == "*" || token == "-" || token == "/"){
int y = num.top();
num.pop();
int x = num.top();
num.pop();
int z = calc(x, y, token);
num.push(z);
}else{
num.push(atoi(token.c_str()));
}
}
return num.top();
}
int calc(int x, int y, string token){
if(token == "+") return x + y;
if(token == "*") return x * y;
if(token == "-") return x - y;
if(token == "/") return x / y;
return 0;
}
int getRank(char ops){
if (ops == '+' || ops == '-') return 1;
if (ops == '*' || ops == '/') return 2;
return 0;
}
};