1006. 笨阶乘
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/clumsy-factorial
题解写的不咋地,嘛,反正也没什么人看。
题目
通常,正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积。例如,factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1。
相反,我们设计了一个笨阶乘 clumsy:在整数的递减序列中,我们以一个固定顺序的操作符序列来依次替换原有的乘法操作符:乘法(*),除法(/),加法(+)和减法(-)。
例如,clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1。然而,这些运算仍然使用通常的算术运算顺序:我们在任何加、减步骤之前执行所有的乘法和除法步骤,并且按从左到右处理乘法和除法步骤。
另外,我们使用的除法是地板除法(floor division),所以 10 * 9 / 8 等于 11。这保证结果是一个整数。
实现上面定义的笨函数:给定一个整数 N,它返回 N 的笨阶乘。
示例 1:
输入:4
输出:7
解释:7 = 4 * 3 / 2 + 1
提示:
1 <= N <= 10000
-2^31 <= answer <= 2^31 - 1
(答案保证符合 32 位整数。)
思路
一开始是先用计算器的思想去做的,搞出答案后发现好像有点规律,找了找结果发现原来很简单= =。最后也是搞出两版代码吧。计算器的怎么说呢,比较乱,但总归是思路,参考参考也没问题。相对于用栈的来说,思路还是简单一点。
看了题解也是知道为什么是这规律了。实话说搞了这么久算法基本上能用上数学公式的真心不是很多,重要的还是思想,今天也是先用算法思想做出来的题,再发现规律最终简化的。也是难得有纯靠数学思维就能做出来的题吧= =。或许也有可能是我还没到那层次吧。
哎,没想到我一直以来引以为靠的数学到了大学没多少能发挥的空间,可能还是我的创造力不太够吧,将数学联系到生活当中的能力并不强。主要还是不太想考研,走软件这条路还是要更多的联系实际吧。再说只要我愿意,到哪里不能学习呢?
代码
// 找到规律后简化的题解
public static int clumsy(int N) {
if (N <= 4) {
switch (N) {
case 4: return 7;case 3: return 6;case 2: return 2;case 1: return 1;case 0: return 0;}}switch (N % 4) {
case 1: return N+2;case 2: return N+2;case 3: return N-1;case 0: return N+1;}return -1;
}
// 计算器的思路
public static int clumsy2(int N) {
// 发现前面的一些数字运算下来答案不一样,就先排除了。if(N <= 6){
switch (N){
case 6: return 8;case 5: return 7;case 4: return 7;case 3: return 6;case 2: return 2;case 1: return 1;case 0: return 0;}}int res = 0;// temp用来保存中间先执行的 *、/ 运算的结果int temp = 0;// 先加了两倍的开头三位的 *、/,后续会减一次。res += 2 * N * (N-1) / (N-2);for (int i = N; i >= 1; i--) {
// 循环处理四种符号的情况:switch ((N - i) % 4) {
case 0:res -= temp;temp = 0;temp += i;break;case 1:temp *= i;break;case 2:temp /= i;break;case 3:res += i;break;}}// 发现少减了一次末尾的,补上:res -= temp;return res;
}