微信公众号:路人zhang
扫码关注微信公众号

回复“面试手册”,获取本站PDF版

回复“简历”,获取高质量简历模板

回复“加群”,加入程序员交流群

回复“电子书”,获取程序员类电子书

当前位置: 算法 > 剑指offer > 剑指offer 14-2.剪绳子2

题目描述

给你一根长度为 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

提示:

  • 2 <= n <= 1000


算法

(数学) O(n)

思路和 剑指 Offer 14- I. 剪绳子 一样,只是 n 的范围扩大成了 1000,在做乘法的时候 res 需要转成 long long 防止爆 int​,Java 转 long

在代码实现上换了一种写法。

时间复杂度

O(n)

空间复杂度

O(1)

C++ 代码

class Solution {
public:
    const int mod = 1e9 + 7;

    int cuttingRope(int n) {
        if (n <= 3) return 1 * (n - 1);

        int res = 1;
        while (n >= 5)  res = (long long)res * 3 % mod, n -= 3; // 先拆 3
        res = (long long)res * n % mod; // 剩下的就是 4 或 2
        if (res == 1000000008) return 1;
        return res;
    }
};

Java 代码

class Solution {
    private static final int MOD = 1000000007;

    public int cuttingRope(int n) {
        if (n <= 3) {
            return 1 * (n - 1);
        }

        int res = 1;
        while (n >= 5) {
            res = (int)((long)res * 3 % MOD);
            n -= 3;
        }
        res = (int)((long)res * n % MOD);
        if (res == 1000000008) {
            return 1;
        }
        return res;
    }
}

Python 代码

class Solution:
    def cuttingRope(self, n: int) -> int:
        MOD = 1000000007

        if n <= 3:
            return 1 * (n - 1)

        res = 1
        while n >= 5:
            res = (res * 3) % MOD
            n -= 3
        res = (res * n) % MOD
        if res == 1000000008:
            return 1
        return res

本文由读者提供Github地址:https://github.com/tonngw


点击面试手册,获取本站面试手册PDF完整版