题目:给一根长度为n的绳子,把绳子剪成整数长度的m段(m,n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1]...k[m-1].问k[0]*k[1]*k[2]*...*k[m-1]可能的最大乘积是多少?例如,当绳子的长度是8时,将它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
本人原本的思路是通过n/m得到的商的小数点是否为0来判断,无法得到最后的理想结果(错误思路)
正确的思路:通过分析得到尽可能切为长度为3的片段,最后得到的乘积最大,则最后变成了3a+b=n这样的函数求最大值。math.pow(x,y)表示x的y次方。
class Solution:
def cuttingRope(self, n: int) -> int:
a,b=n//3,n%3
if n<=3: return n-1
if b==0: return int(math.pow(3,a))
if b==1: return int(math.pow(3,a-1)*4)
else: return int(math.pow(3,a)*2)
剑指offer14-II剪绳子:考虑大数越界的情况下的求余问题。可能超过int的范围
大数求余方法包括循环求余(O(N))和快速幂(log2(N))求余。第二者的时间复杂度更低.
循环求余思想:
快速求幂数学思想:
快速幂求余代码:
def remainder(x,a,p):
rem=1
while a>0:
if a%2:rem=(rem*x)%p
x=x**2%p
a=a//2
return rem
本题考虑大数越界时的代码:
class Solution:
def cuttingRope(self, n: int) -> int:
if n<=3:return n-1
a,b,p,x,rem=n//3-1,n%3,1000000007,3,1
while a>0:
if a%2:rem=(rem*x)%p
x=x**2%p
a=a//2
if b==0:return (rem*3)%p
elif b==1: return (rem*4)%p
else: return (rem*6)%p