剑指offer-剪绳子(递归、动规、贪心)

1.题目描述

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

2.来源

https://www.nowcoder.com/practice/57d85990ba5b440ab888fc72b0751bf8?tpId=13&&tqId=33257&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

3.编吧

3.1递归

(1)确定递归公式: f(n) = max(f(i)*f(n-i)),其中0

(2)找到“递归出口”:if:target < 4;return:target

3.2动态规划

自下而上的求解问题;先计算小问题的最优解并存储下来,再以此为基础求解大问题的最优解

3.3.贪心算法

数学问题;

当n≥5的时候,2(n-2)>n,3(n-3)>n;

也就是说当剩下绳子的长度≥5的时候,可以发现3(n-3)>2(n-2)

因此我们应该尽可能多的剪成长度为3的段(前提n>5)

当n=4的时候,2*2>1*3,所以这时候均分两段最为合适。

4.Code Show

4.1递归

import java.util.*;
public class Solution {
    public int cutRope(int target) {
        
        if(target < 2)
            return 0;
        if(target == 2) return 1;
        if(target == 3) return 2;
        
        return cutRopeInternal(target);
    }
    
    public int cutRopeInternal(int length){
        //递归出口
        if(length < 4)
            return length;
        //递归
        int max = 0;
        for(int i = 1;i <= length/2;i++){
            max = Math.max(cutRopeInternal(i)*cutRopeInternal(length-i),max);
        }
        return max;
    }
}

4.2动态规划

import java.util.*;
public class Solution {
    public int cutRope(int target) {
        
        if(target < 2)
            return 0;
        if(target == 2) return 1;
        if(target == 3) return 2;
        
        //申请额外的存储空间
        int[] products = new int[target+1];
        //对前几个初始值进行赋值操作
        products[0] = 0;
        products[1] = 1;
        products[2] = 2;
        products[3] = 3;
        //动态规划,自下而上进行
        int max = 0;
        for(int i=4;i<=target;++i){
            max = 0;
            for(int j = 1;j <= i/2;++j){
                max = Math.max(products[j]* products[i-j],max);
            }
            products[i] = max;
        }
        max = products[target];
        return max;
    }
}

4.3贪心算法

import java.util.*;
public class Solution{
    public int cutRope(int target) {
        if(target < 2)
            return 0;
        if(target == 2) return 1;
        if(target == 3) return 2;
        
        int timeof3 = target/3;
        if((target - timeof3*3) == 1)
            timeof3 -= 1;
        int timeof2 = (target - timeof3*3)/2;
        return (int)(Math.pow(3,timeof3)*Math.pow(2,timeof2));
    }
}

 

你可能感兴趣的:(Java,算法)