leetcode-剪绳子

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

 示例1:

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

 示例2:

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

 首先讲一下我自己的做法,根据均值不等式我们知道要使乘积最大,那么就要使各段的长度最接近,比如分成3,3就比4,2好,所以可以这么做,先均分成m段整数长度,如果还有剩下的长度再继续均分(这个时候只有部分能分到了)。举个例子,n=11的情况下,假设m=3,先均分成3段长度为3的,然后还剩下长度11-9=2,再将这个个长度2均分给其中两段得到4,4,3,这就是在3段的情况下的最好情况了,然后我们需要遍历m2~n的所有情况,返回其中的最大结果。因为pow()的时间复杂度是 O ( 1 ) O(1) O(1),所以总时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)

 JAVA版代码如下:

class Solution {
    public int cuttingRope(int n) {
        int result = 0;
        for (int i = 2; i <= n; ++i) {
            int ave = n / i;
            int res = n % i;
            int cur = (int)(Math.pow(ave, i - res) * Math.pow(ave + 1, res));
            result = Math.max(result, cur);
        }
        return result;
    }
}

 提交结果如下:


 Python版代码如下:

class Solution:
    def cuttingRope(self, n: int) -> int:
        result = 0
        for i in range(2, n + 1):
            ave = n // i
            res = n % i
            cur = (int)(math.pow(ave, i - res) * math.pow(ave + 1, res))
            result = max(result, cur)
        return result

 提交结果如下:


 然后是动态规划的方法,假设dp[i]代表长度为i的绳子所能得到的最大乘积。假设这里最后一段剪出来的绳子长度为i-jj的范围为1~i-1),那么前面长度为j的绳子的最大乘积即为dp[j](也被剪成段了)或j(没被剪成段),所以dp[i]=max(j*(i-j), dp[j]*(i-j)),这就是我们需要的递推公式。因为需要两层循环,所以时间复杂度为 O ( n 2 ) O(n^{2}) O(n2),空间复杂度为 O ( n ) O(n) O(n)

 JAVA版代码如下:

class Solution {
    public int cuttingRope(int n) {
        int[] dp = new int[n + 1];
        for (int i = 2; i <= n; ++i) {
            for (int j = 1; j < i; ++j) {
                dp[i] = Math.max(dp[i], Math.max(j * (i - j), dp[j] * (i - j)));
            }
        }
        return dp[n];
    }
}

 提交结果如下:


 最后还有一种需要数学推导的方法,具体看这里。时间复杂度和空间复杂度均为 O ( 1 ) O(1) O(1)

 JAVA版代码如下:

class Solution {
    public int cuttingRope(int n) {
        if (n <= 3) {
            return n - 1;
        }
        int p = n / 3;
        int q = n % 3;
        if (q == 2) {
            return (int)Math.pow(3, p) * 2;
        }
        if (q == 1) {
            return (int)Math.pow(3, p - 1) * 4;
        }
        return (int)Math.pow(3, p);
    }
}

 提交结果如下:


你可能感兴趣的:(LeetCode,leetcode,算法,java,python,动态规划)