笨阶乘C++解法详解(力扣1006)

问题解析 :LeetCode 1006 "笨阶乘"要求对正整数 N 按递减顺序依次使用乘 *、除 /、加 +、减 - 四个运算符循环计算,即 clumsy(N) = N * (N-1) / (N-2) + (N-3) - (N-4) * (N-5) / (N-6) + ...,需返回计算结果。核心在于处理运算符优先级(乘除优先于加减)和循环模式。

解法对比

方法 核心思路 时间复杂度 空间复杂度 适用场景
栈模拟 用栈存储中间结果,按运算符优先级处理 O(N) O(N) 通用性强,直观模拟运算过程
数学归纳 观察规律,推导出分段计算公式 O(1) O(1) 效率最高,直接计算

方法一:栈模拟法

通过栈保存待计算的值,遇到乘除立即计算,加减则入栈(减法转为加负数),最后对栈中所有元素求和。

cpp 复制代码
#include <stack>
#include <vector>
using namespace std;

class Solution {
public:
    int clumsy(int N) {
        stack<int> stk;
        stk.push(N);
        N--;
        int index = 0; // 用于循环运算符:0:*, 1:/, 2:+, 3:-
        while (N > 0) {
            if (index % 4 == 0) { // 乘法 int top = stk.top();
                stk.pop();
                stk.push(top * N);
            } else if (index % 4 == 1) { // 除法 int top = stk.top();
                stk.pop();
                stk.push(top / N);
            } else if (index % 4 == 2) { // 加法
                stk.push(N);
            } else { // 减法:转为加负数
                stk.push(-N);
            }
            index++;
            N--;
        }
        // 对栈中所有元素求和 int sum = 0;
        while (!stk.empty()) {
            sum += stk.top();
            stk.pop();
        }
        return sum;
    }
};
  • 时间复杂度:O(N),遍历 N 次。
  • 空间复杂度:O(N),栈最多存储约 N/2 个元素。

方法二:数学归纳法(O(1))

通过观察 N 较大时的计算规律,可发现每 4 个数一组 (N * (N-1) / (N-2) + (N-3))的结果近似为 N+1,剩余部分可推导出分段公式 :

  • N ≤ 2:直接返回 N。
  • N == 3 :返回 6(即 3 * 2 / 1)。
  • N == 4 :返回 7(即 4 * 3 / 2 + 1)。
  • N > 4
    • N % 4 == 0:结果为 N + 1
    • N % 4 == 1N % 4 == 2:结果为 N + 2
    • N % 4 == 3:结果为 N - 1
cpp 复制代码
class Solution {
public:
    int clumsy(int N) {
        if (N <= 2) return N;
        if (N == 3) return 6;
        if (N == 4) return 7;
        // 根据 N 对 4 取余的结果返回对应值
        if (N % 4 == 0) return N + 1;
        if (N % 4 == 1 || N % 4 == 2) return N + 2;
        return N - 1; // N % 4 == 3
    }
};
  • 时间复杂度:O(1)。
  • 空间复杂度:O(1)。

推荐使用数学归纳法,其效率最高,代码简洁。栈模拟法虽直观,但效率较低,适用于需要严格模拟运算过程的场景。


参考来源

相关推荐
无限的鲜花1 小时前
协程本质是函数加状态机——零基础深入浅出 C++20 协程
c++·算法·c++20
逝水无殇2 小时前
C# 字符串(String)详解
开发语言·后端·c#
精明的身影2 小时前
C++自学之路1:Hello world
开发语言·c++
旖-旎2 小时前
《LeetCode 64 最小路径和 || LeetCode 174 地下城游戏》
c++·算法·leetcode·动态规划
森林古猿12 小时前
再论斜率优化
c++·学习·算法
leo__5202 小时前
基于导航数据的扩展卡尔曼滤波(EKF)MATLAB 实现
开发语言·matlab
万法若空2 小时前
【数学-简单数论】同余中的逆
线性代数·算法
水利行业RTU手艺人2 小时前
RTU固件中的“数据保险箱”——离线数据补发系统设计
c++·stm32·单片机·物联网
gugucoding3 小时前
25. 【C语言】二进制文件与随机读写
c语言·开发语言
北极星日淘3 小时前
中古货品品相评级算法实战|Java权重计分实现标准化五级品相体系
开发语言·python