leetcode -- Basic Calculator I &II --重点,未完全理解
2015-12-16 12:33
459 查看
Basic Calculator
https://leetcode.com/problems/basic-calculator/此题目要求没有负号,所以降低了难度
思路1 转换成reverse polish,再使用stack
http://bookshadow.com/weblog/2015/06/09/leetcode-basic-calculator/思路2 维护一个sign的stack就行
/article/4901785.html这个效率高。不太好理解。看https://leetcode.com/discuss/39532/easy-18-lines-c-16-lines-python
def calculate(self, s): total = 0 i, signs = 0, [1, 1] while i < len(s): c = s[i] if c.isdigit(): start = i while i < len(s) and s[i].isdigit(): i += 1 total += signs.pop() * int(s[start:i]) continue if c in '+-(': signs += signs[-1] * (1, -1)[c == '-'], elif c == ')': signs.pop() i += 1 return total
思路3 用two stacks 求中缀表达式
/article/4719035.htmlhttps://leetcode.com/discuss/39509/ac-c-solution-with-two-stacks
规则
- 规定左括号优先级最低,但是遇到左括号的时候不比较优先级直接Push
- 遇到右括号的时候,则要一直pop,并计算结果,push到operend stack,直到把左括号pop出来,
- 遇到其余operators, 则必须比较优先级,如果优先级大于栈顶元素才push否则计算operend stack 前两元素的结果
- 如果遇到负号,那么负号也看做operator,优先级最高。如果前一个字符为’)’或者数字的时候,是减号,其余都是负号。注意区分!
- 如果表达式scan完之后,operator的stack不为空,那么就从栈顶逐个pop计算结果push到operend stack,直到operator stack为空,剩下在operend的值就是结果
总的来说 operators 含有 +-*/以及负号,左右括号
思路4
左括号以及操作符入op stack,数字入num stack。遇到右括号就计算临时结果,这里用两个临时stacks将中缀转换成了后缀。计算完遇到右括号的结果之后,如果最后没有了括号,那么再做一次中缀转后缀就行。code 用http://yucoding.blogspot.hk/2015/10/leetcode-question-basic-calculator.html的
class Solution(object): def compute(self, num, ops): while len(ops) != 0: op = ops.pop() if op == '+': num.append(num.pop() + num.pop()) else: num.append(num.pop() - num.pop()) return num[-1] def calculate(self, s): """ :type s: str :rtype: int """ #remove spaces s = s.replace(' ', '')#去掉space #double stacks num = [] ops = [] i = 0 n = '' while i < len(s): if s[i] >= '0' and s[i] <='9':#找到string s中的数字 n = n + s[i] i += 1 else: if n != '':#n为数字 num.append(int(n)) n = '' if s[i] == ')': tmp_num = [] tmp_ops = [] while ops[-1]!= '(': #把num和ops中的元素倒置,因为 for expression 1-2+3, the output from stack is 3, 2, 1 and + , -, 3+2-1 is NOT equal to 1-2+3. tmp_ops.append(ops.pop()) tmp_num.append(num.pop()) tmp_num.append(num.pop())#加上括号内离左括号最近的数 ops.pop()#pop掉左括号 num.append( self.compute(tmp_num, tmp_ops) ) else: ops.append(s[i]) i += 1 #对于i scan到的最后一个操作数,表达式最末尾的操作数 if n!= '': num.append(int(n)) #上面只有在遇到右括号的时候进行了表达式计算,这里对于剩下的没有括号的表达式进行计算。 tmp_num = []#这里相当于中缀转换为后缀 tmp_ops = [] while len(ops) != 0: tmp_ops.append(ops.pop()) tmp_num.append(num.pop()) tmp_num.append(num.pop()) return self.compute(tmp_num, tmp_ops)
Basic Calculator II
也不要求考虑负号,降低了难度。可以用上述的中缀表达式求值。
参考
http://yucoding.blogspot.hk/2015/10/leetcode-question-basic-calculator-ii.html
这里看ref里面的思路,很好理解。num[i]和num[i+1]对应ops[i]这个操作数,算出来的结果放到num[i]就行了。
class Solution(object): def calculate(self, s): """ :type s: str :rtype: int """ # remove spaces s = s.replace(" ","") num = [] # list of numbers ops = [] # list of operators # read numbers and operators from string i = 0 n = "" while i < len(s): if '9'>= s[i] >= '0': n = n + s[i] else: num.append(int(n)) n = "" ops.append(s[i]) i+=1 if len(n) != 0: num.append(int(n)) # compute all the * and / operations i = 0 while i < len(ops):#这里十分巧妙,记住! if ops[i] == '*': num[i] = num[i] * num[i+1] num.pop(i+1) ops.pop(i) elif ops[i] == '/': num[i] = num[i] / num[i+1] num.pop(i+1) ops.pop(i) else: i += 1 # compute all the + and - operations i = 0 while i < len(ops): if ops[i] == '+': num[i] = num[i] + num[i+1] num.pop(i+1) ops.pop(i) elif ops[i] == '-': num[i] = num[i] - num[i+1] num.pop(i+1) ops.pop(i) return num[0]
相关文章推荐
- GPS定位系统的介绍
- 编译器错误消息: CS0016: 未能写入输出文件
- Objective-C_OC中的方法
- 【第四篇章-android平台MediaCodec】推断是否支持硬件解码码
- LeetCode Palindrome Number
- mysql 查询优化
- 栈的顺序表示和实现
- linux select例子
- 设计模式:0. 设计原则
- Unity Networking API文档翻译(二):The High Level API
- ssh -CT -o BatchMode=yes 用户名@主机名
- 考拉社区深度打造“智鲜乐”生活社区
- 修改IOS程序名称
- Ubuntu/Linux apache启动、重启、停止操作指令
- 欢迎使用CSDN-markdown编辑器
- 控制多组图片
- 190. Reverse Bits (Int; Bit)
- 第二次编程练习
- JavaScript改变 HTML 内容
- 链表及操作