Daily算法刷题【面试经典150题-3️⃣】
文章目录
- 📕栈
- 1.有效的括号
- 2.简化路径(🎈)
- 3.最小栈(🍭)
- 4.逆波兰表达式求值(🎈🎉)
- 5.基本计算器(💣❗️)
📕栈
1.有效的括号
class Solution {
public:bool isValid(string s) {stack<char> st;map<char, char> mp;mp[')'] = '(';mp['}'] = '{';mp[']'] = '[';for(char x : s){if(x == '(' || x == '{' || x == '['){st.push(x);}else{if(!st.empty() && st.top() == mp[x]){st.pop();}else{return false;}}} return st.empty();}
};
2.简化路径(🎈)
🎈法1:使用vector模拟
class Solution {
public:string simplifyPath(string path) {vector<string> st; // 用vector模拟栈来存储路径组件int i = 0;int n = path.size();// 遍历整个路径字符串while(i < n) {// 跳过连续的斜杠 '/'while(i < n && path[i] == '/') ++i;if(i == n) break; // 如果已经到字符串末尾,退出循环// 找到下一个斜杠之前的内容int j = i;while(j < n && path[j] != '/') ++j;// 提取两个斜杠之间的字符串string str = path.substr(i, j - i);// 处理提取到的路径if(str != ".") { // 当前路径无需处理if(str == ".." && !st.empty()) st.pop_back(); // 遇到".."且栈不为空,返回上一级目录else if(str != "..") st.push_back(str); // 普通目录名,入栈}i = j; // 移动到下一个位置继续处理}// 构建结果字符串if(st.empty()) return "/"; // 如果栈为空,返回根目录string ans;for(string str: st) {ans = ans + ('/' + str); // 在每个目录前添加斜杠}return ans;}
};
法2:vector
class Solution {
public:string simplifyPath(string path) {stack<string> st;int i = 0;int n = path.size();while(i < n){while(i < n && path[i] == '/') ++i;if(i == n) break;int j = i;while(j < n && path[j] != '/') ++j;string cur = path.substr(i, j - i);if(cur == ".."){if(!st.empty()){st.pop();}}else if(cur != "."){st.push(cur);}i = j;}vector<string> vec;if(st.empty()) return "/";while(!st.empty()){vec.push_back(st.top());st.pop();}string ans = "";for(int i = vec.size() - 1; i >= 0; i--){ans = ans + ('/' + vec[i]);}return ans;}
};
3.最小栈(🍭)
法1:辅助栈
一个栈操作数,另一个保存最小值
/*时间复杂度: O(1)空间复杂度: O(n)
*/
class MinStack {stack<int> val_stack;stack<int> min_stack;public:MinStack() {min_stack.push(INT_MAX);}void push(int val) {val_stack.push(val);min_stack.push(min(min_stack.top(), val));}void pop() {val_stack.pop();min_stack.pop();}int top() {return val_stack.top();}int getMin() {return min_stack.top();}
};/*** 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();*/
法2:栈+元祖(👍)
发现了一个更简洁的写法,虽然本质和法1是一样的
/*时间复杂度: O(1)空间复杂度: O(n)
*/
class MinStack {stack<pair<int, int>> st;public:MinStack() {st.push({-1,INT_MAX});}void push(int val) {st.push({val, min(val, st.top().second)});}void pop() {st.pop();}int top() {return st.top().first;}int getMin() {return st.top().second;}
};/*** 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();*/
4.逆波兰表达式求值(🎈🎉)
法1:栈实现后缀表达式计算
主要就是从左到右遍历后缀表达式,遇到数就加入栈,遇到操作符就从栈中取出两个数字进行计算即可(需要注意取出来的数的运算顺序)
/*时间复杂度:O(n)空间复杂度:O(n)
*/
class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;int n = tokens.size();for(int i = 0; i < n; i++){if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){// 注意操作数顺序 是b op a先弹出来的是被操作数int b = st.top(); st.pop();int a = st.top(); st.pop(); string op = tokens[i];int cur = 0;if(op == "+") cur = a + b;else if(op == "-") cur = a - b;else if(op == "*") cur = a * b;else cur = a / b;st.push(cur); }else{// stoi:字符串转数字int num = stoi(tokens[i]);st.push(num);}}return st.top();}
};
法2:unorderedmap
看到一种更好维护的方法
class Solution {
public:int evalRPN(vector<string>& tokens) {unordered_map<string, function<int(int,int)>>map={{"+",[](int a,int b){return a + b;}},{"-",[](int a,int b){return a - b;}},{"*",[](int a,int b){return a*b;}},{"/",[](int a,int b){return a/b;}}};stack<int> st;for(string s : tokens){if(map.count(s)){int b = st.top(); st.pop();int a = st.top(); st.pop();st.push(map[s](a,b));}else{st.push(stoi(s));}}return st.top();}
};
5.基本计算器(💣❗️)
太难了qaq~
这个题只有加减法,其实就是去括号变号的过程,使用一个栈保存当前的符号
/*时间复杂度:O(n)空间复杂度:O(n)
*/
class Solution {
public:int calculate(string s) {stack<int> ops;ops.push(1);int sign = 1;int res = 0;int n = s.size();int i = 0;while(i < n){if(s[i] == ' '){i++;}else if(s[i] == '+'){sign = ops.top();i++;}else if(s[i] == '-'){sign = -ops.top();i++;}else if(s[i] == '('){ops.push(sign);i++;}else if(s[i] == ')'){ops.pop();i++;}else{long val = 0;while(i < n && s[i] >= '0' && s[i] <= '9'){val = val * 10 + s[i] - '0';i++;}res += sign*val;}}return res;}
};