leetcode刷题 剑指 Offer 14- II. 剪绳子 II
一、题目
剑指 Offer 14- II. 剪绳子 II
难度中等125
给你一根长度为 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。
二、思路
2.1 贪心算法
可以由数学推导得到(列出算式,求导):
切分规则:
最优: 3 。把绳子尽可能切为多个长度为 3 的片段,留下的最后一段绳子的长度可能为 0,1,2 三种情况。
次优: 2 。若最后一段绳子长度为 2 ;则保留,不再拆为 1+1 。
最差: 11。若最后一段绳子长度为 1 ;则应把一份 3 + 1 替换为 2 + 2,因为 2×2>3×1。
代码
class Solution {
public int cuttingRope(int n) {
int i=0;
long sum=1;
if(n==1) return 1;
if(n==2) return 1;
if(n==3) return 2;
while(n>4){
sum=sum*3;
sum=sum%1000000007;
n=n-3;
}
return (int)(sum * n % 1000000007);
}
}
有关int和long型数据范围的分析
(1) int型一共32位,有一位作为符号位,其数据范围是-2^31 ~ 2^31,
即-2147483648 ~ 2147483647;
近似范围可以记为-2000000000 ~ 2000000000 即 - 2 × 10^9 ~ 2 × 10^9
本题中给的模数为1 × 10^9 + 7(1000000007),若再乘以3,就超过了int型的范围,所以要使用long存储结果才不会溢出
(2) long型一共64位,对应int型的方式,long型数据范围可以简单记为:
-8 × 10^18 ~ 8 × 10^18
本题的1000000007平方小于2 × 10^18,所以用long存储模数的平方也是没有问题的