LeetCode每日一题:1006. 笨阶乘

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. 1 <= N <= 10000
  2. -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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值