剑指offer——剪绳子

题目描述:给你一根长度为n的绳子,请把绳子剪成整数长的m段(mn都是整数,n>1并且m>1m<=n),每段绳子的长度记为k[1],...,k[m]...。请问k[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为233的三段,此时得到的最大乘积是18。

输入描述:输入一个数n,(2 <= n <= 60)

返回值描述:输出答案

示例1:

输入: 

8

返回值:

18

思路及解答:

每个长度的绳子,要么最长的情况是不剪开(长度是本身),要么长度是剪开两端的乘积。因此每个长度length都需要遍历两个相加之后等于length的乘积,取最大值。初始化值 长度为1的值为1,从长度为2开始,每种长度都需要遍历两个字长度的乘积。

Java实现代码如下所示:

public class Solution{
    public int cutRope(int target){

        if(target <= 1){
            return target;
        }
        int[] nums = new int[target + 1];
        nums[1] = 1;
        nums[0] = 1;
        for(int i = 2 ; i <= target ; i++){
            int max = i;
            for(int j = 0 ; j <= i/2 ; j++){
                int temp = nums[j] * nums[i -j];
                if(temp > max){
                    max = temp;
                }
            }
            nums[i] = max;
        }
        return nums[target];
    }
}

采用动态规划的方法来解题:假设绳子长度为n的最大的长度为f(n),那么如何计算f(n)?

f(n)可能是n,不切分的情况下

f(n)可能是f(n-1)和f(1)的乘积

f(n)可能是f(n-2)和f(2)的乘积

……

因此,要想求f(n),我们必须先把f(n-1),f(n-2)……之类的前面值先求出来,f(1) = 1,这是初始值

Java实现代码如下所示:

public class Solution{
    public int cutRope(int target){\

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

时间复杂度:O(n^2) 空间复杂度:O(n),需要创建额外的二维数组

你可能感兴趣的:(剑指offer刷题,算法,java,开发语言,数据结构,leetcode,intellij-idea,动态规划)