各位题友大家好! 今天是 @负雪明烛 坚持日更的第 67 天。今天力扣上的每日一题是「1006. 笨阶乘」。
解题思路
3 月的每日一题中,我们已经做过了 150. 逆波兰表达式求值 这个题目。表达式求值的题目一通百通。今天的题目其实也是个数学表达式求值。
先解释一下题意:对于输入的 n,要求 n 的笨阶乘。也就是要求表达式 n * (n - 1) / (n - 2) + (n - 3) - (n - 4) * (n - 5)....1
的值,其中的符号是按照 [*, / , +, -]
这个数学依次循环添加进去的。
我们知道求解没有括号的表达式的时候,运算符是优先级的:先乘除,后加减。
我们平时见到的运算表达式是中缀表达式,即 "操作数① 运算符② 操作数③"
的顺序,运算符在两个操作数中间。
类似的还有后缀表达式**是 "操作数① 操作数③ 运算符②"
** 的顺序,运算符在两个操作数之后。
对于表达式求值,大家已经很熟悉了,需要用「栈」这个数据结构。求解没有括号的中缀表达式的时候,可以用一句顺口溜来概括:遇到乘除立即算,遇到加减先入栈。
- 「乘除立即算」的含义是把栈顶元素和当前元素进行
*
或者/
的计算
- 「加减先入栈」的含义是如果当前操作符是+
则直接把当前数字进栈,如果当前操作符是-
则把当前数字取反放入到栈中。
以 clumsy(10) = 10 9 / 8 + 7 - 6 5 / 4 + 3 - 2 * 1 为例,用动画解释一下这个过程:
该动画对应的 PPT 如下,可以逐步观看:
Python 躲坑
如果你使用 Python 刷题,需要注意下面的这个坑。其他语言可以不看这部分。
python 的整数除法是向下取整,而不是向零取整,对于负数的除法会有问题。
- python2 的除法 “/“ 是整数除法,
"-3 / 2 = -2"
; - python3 的地板除 “//“ 是整数除法,
"-3 // 2 = -2"
; - python3 的除法 “/“ 是浮点除法,
"-3 / 2 = -1.5"
;
而 C++/Java 中的整数除法是向零取整。
- C++/Java 中
"-3 / 2 = -1"
.
本题的题意(一般情况)都是要求向零取整的。
解决方法 1
对 Python 的整数除法问题,可以用 int(num1 / float(num2))
来做,即先用浮点数除法,然后取整。
- 无论如何,浮点数除法都会得到一个浮点数,比如
"-3 / 2.0 = 1.5"
;
- 此时再取整,就会得到整数部分,即float(-1.5) = -1
。
解决方法 2
使用库函数 operator.truediv(num1, num2)
,调用该函数等价于 num1 / float(num2)
。
代码
代码如下,挺简洁的。
class Solution(object):
def clumsy(self, N):
op = 0
stack = [N]
for i in range(N - 1, 0, -1):
if op == 0:
stack.append(stack.pop() * i)
elif op == 1:
stack.append(int(stack.pop() / float(i)))
elif op == 2:
stack.append(i)
elif op == 3:
stack.append(-i)
op = (op + 1) % 4
return sum(stack)
- 时间复杂度:$O(N)$
- 空间复杂度:$O(N)$
刷题心得
数学表达式求值,一般都用到「栈」;
- 表达式求值的难点在于各个操作符的优先级;
- 不要看到题目长、题目新,就害怕啊,其实不难的;本题不能直接使用
eval()
,这相当于作弊。
参考资料:
力扣官方题解
OK,以上就是 @负雪明烛 写的今天题解的全部内容了,如果你觉得有帮助的话,求赞、求关注、求收藏。如果有疑问的话,请在下面评论,我会及时解答。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
祝大家牛年大吉!AC 多多,Offer 多多!我们明天再见!