【LeetCode】【剑指offer】【剪绳子(二)】

发布于:2023-01-19 ⋅ 阅读:(206) ⋅ 点赞:(0)

剑指 Offer 14- II. 剪绳子 II

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m - 1] 。请问 k[0]*k[1]*...*k[m - 1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:

输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/jian-sheng-zi-ii-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

 

乍一看,这道题和剪绳子(一)没啥区别,细一看,这道题要求将结果取模,

好家伙,这道题的每一个测试用例都非常大,非常容易发生溢出的情况

我们需要针对剪绳子(一)的写法进行一些调整

置于具体的算法此处不再做解释,直接参考

【LeetCode】【剑指offer】【剪绳子(一)】_桜キャンドル淵的博客-CSDN博客 

循环幂求余法 

这里针对于大数,我们在每一次乘法,的时候都需要模上 1000000007,

并且将我们的x,res修改成long int(已经测过int的话会溢出) 

class Solution {
public:
    int cuttingRope(int n) {
        if(n<=3)
        {
            return n-1;
        }
        long int x=n/3;
        int y=n%3;
        long int res=1;
        if(y==0)
        {
            while(x--)
            {
                res=(3*res)%1000000007;
            }
            return res;

        }
        if(y==1)
        {
            x=x-1;
            while(x--)
            {
                res=(3*res)%1000000007;
            }
            res=(res*4)%1000000007;
            return res;
        }
        while(x--)
        {
            res=(3*res)%1000000007;
        }
        res=(res*2)%1000000007;
        return res;

    }
};

快速幂算法

假如要求3^{5},由于五是奇数,所以我们可以把一个3提取出来,变成3^{4}乘3

然后3的四次方是偶数,可以拆分为3^{2}×3^{2}

也就是说计算3^{5}其实只需要先算出3的平方9,然后再算出9的平方81,最后再乘上那个单独的3就可以得出243了。

 下面我们就定义了一个remainder来实现我们的上述算法

class Solution {
public:
    
    //x的值一定要是long,否则会存不下
    //返回的remainder的值也一定要是long否则会存不下
//x为底数,a为指数,p为要取的模
    long remainder(long x,int a,long p)
    {
//rem为我们最终快速幂乘法的返回结果
        int rem=1;
        while (a>0)
        {
//如果a是奇数的话,我们就直接将这个多出来的底数乘给我们的返回结果
//并且每一步运算都要对p取模防止溢出
            if ((a%2)==1)
            {
                rem=(rem*x)%p;
            }
//如果是偶数的话,就直接平方再取模
            x=(x*x)%p; 
//然后我们的指数就可以直接整除2了
//这样就实现了快速幂算法
            a/=2;
        }
        return rem;
    }

//下面对我们之前的代码进行一些微调即可
    int cuttingRope(int n) {
        long p=1000000007;
         if(n<=3)
        {
            return n-1;
        }
        long int x=n/3;
        int y=n%3;
        long int res=1;
        if(y==0)
        {
            return remainder(3,x,p);
        }
        if(y==1)
        {
            x=x-1;
            res=(remainder(3,x,p)*4)%p;
            return res;
        }
        res=(remainder(3,x,p)*2)%p;
        return res;

    }
};

 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到