idea:刚开始是打算分类讨论,建立了数字栈和字符栈,按照传入字符当时两个栈的基本情况分类,结果讨论完之后分类太麻烦,导致分析完了之后漏洞不少。我觉得这道题难点在于括号和负号的处理,一开始将导致计算机出错的情况当成了重点,所以思路错了。
idea:下面的题解是遇到一个数处理一个数,无论该数是在括号里边还是外边,都将其按照括号展开后的情况直接加或减进行处理。在这里编者运用了sign记录了每一个数前边的符号情况,并且考虑了连续数字在字符串中的处理,如12+14实际上是五个字符
题解:
class Solution { public: int calculate(string s) { stack<int> ops; //建立栈,仅用来储存当前位置的数字在括号展开后的实际符号情况 ops.push(1); //基础符号默认为+ int sign = 1; //默认为+int ret = 0; //当前得数 int n = s.length(); int i = 0; while (i < n) { if (s[i] == ' ') { i++; } else if (s[i] == '+') { sign = ops.top(); //“+”对sign值不产生影响 i++; } else if (s[i] == '-') { sign = -ops.top(); //“-”要变号 i++; } else if (s[i] == '(') { ops.push(sign); //遇到左括号将当前基础符号压入栈,即如果括号前是“-”,将“-1”入栈,在括号里边遇到“-”时sign为“+1”,遇到“+”是sign为“-1”。括号前是“+”,则与主式基础符号相同 i++; } else if (s[i] == ')') { //遇到右括号说明括号结束,将括号中的基础符号弹出栈 ops.pop(); i++; } else { //遇到数字则开始计算 long num = 0; //计算当前遇到的数字实际大小,例如连续遇到字符'3'和'5',实际上为35,则num记为int值35 while (i < n && s[i] >= '0' && s[i] <= '9') { //考虑遇到连续字符的情况,即参与运算的不一定都是个位数,在这里用一个循环继续遍历后续的数字字符 num = num * 10 + s[i] - '0'; //百位*100,十位*10,个位*1 i++; } ret += sign * num; //根据sign值判断是加上当前数还是减去 } } return ret;
} };
复杂度分析
时间复杂度:O(n)O(n),其中 nn 为字符串 ss 的长度。需要遍历字符串 ss 一次,计算表达式的值。
空间复杂度:O(n)O(n),其中 nn 为字符串 ss 的长度。空间复杂度主要取决于栈的空间,栈中的元素数量不超过 nn。
明天再看其他的题解,没想到一道题做到半夜两点,结果连答案都分析了好半天才看懂
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TRANSLATE with x English TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back 标签:LeetCode224,基本,int,题解,复杂度,括号,location,&&,计算器 From: https://www.cnblogs.com/Ting-LOVE/p/16793448.html