开两个栈,一个记录数字,一个记录操作符。
然后从前往后扫描整个表达式:
1. 如果遇到 (、+、-,直接入栈;
2. 如果遇到数字,则判断操作符栈的栈顶元素,如果不是 (,则弹出操作符的栈顶元素,并用相应操作更新数字栈的栈顶元素。从而保证操作符栈的栈顶最多有一个连续的+或-;
3. 如果遇到 ),此时操作符栈顶一定是 (,将其弹出。然后根据新栈顶的操作符,对数字栈顶的两个元素进行相应操作;
时间复杂度分析:每个数字和操作进栈出栈一次,所以总时间复杂度是 O(n)
class Solution { public: void calc(stack<char>& op, stack<int>& num){ int y = num.top(); num.pop(); int x = num.top(); num.pop(); if(op.top() == '+') num.push(x+y); else num.push(x-y); //这里一定是先进栈的x减去后进栈的y op.pop(); } int calculate(string s) { //s 中包含 ( ) + - 非负整数 空格 // two stacks: one records numbers, one records operations stack<int> num; stack<char> op; for(int i=0; i<s.size(); i++){ char c = s[i]; if(c == ' ') continue; if(c == '+' || c == '-' || c == '(') op.push(c); else if(c == ')'){ op.pop(); if(op.size() && op.top()!='(') calc(op, num); } else{ int j = i; while(j<s.size() && isdigit(s[j])) j++; num.push(atoi(s.substr(i, j-i).c_str())); // num.push(stoi(s.substr(i, j-i))); i = j-1; if(op.size() && op.top()!='(') calc(op, num); } } return num.top(); } };
用一个栈来保存前一个运算符号与相邻数字的计算结果:用 sign 来记录前一个运算符,若sign为 * 或 / 则将计算出的结果压入栈中;若sign为 + 或 - 则将数字带上符号位压入栈中。
class Solution { public: int calculate(string s) { if(s.size() == 0) return 0; int res = 0; stack<int> st; // 运算符为+ - 时将数字压栈,op为 * / 时把栈顶弹出并与数字做乘或除 // sign 来记录前一个运算符 char sign = '+'; int num = 0; for(int i=0; i<s.size(); i++){ char c = s[i]; if(c>='0' && c<='9'){ num *= 10; num = num - '0' + c; } if(c=='+' || c == '-' || c == '*' || c=='/' || i == s.size()-1){ if(sign == '+') st.push(num); if(sign == '-') st.push(-num); if(sign == '*'){ int t = st.top(); st.pop(); st.push(t*num); } if(sign == '/'){ int t = st.top(); st.pop(); st.push(t/num); } sign = s[i]; num = 0; } } while(!st.empty()){ int t = st.top(); res += t; st.pop(); } return res; } };
参考连接:cnblogs.com/baozitraining/p/11403384.html
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class BSTIterator { private: stack<TreeNode*> st; public: BSTIterator(TreeNode* root) { TreeNode* cur = root; while(cur != NULL){ st.push(cur); cur = cur->left; } } /** @return the next smallest number */ int next() { TreeNode* node = st.top(); st.pop(); TreeNode* r = node->right; while(r){ st.push(r); r = r->left; } return node->val; } /** @return whether we have a next smallest number */ bool hasNext() { return !st.empty(); } }; /** * Your BSTIterator object will be instantiated and called as such: * BSTIterator* obj = new BSTIterator(root); * int param_1 = obj->next(); * bool param_2 = obj->hasNext(); */