剑指offer 14- II. 剪绳子 II
题目描述
解题思路
此题在剪绳子Ⅰ的基础上,多了个取余,因此不能用 Math.pow 方法,需要自己实现求幂。
这里使用快速幂,可以当做模板,时间为o(logn),空间为o(1)。主要优化点是用右移运算符代替了除以2,用位与运算符代替了求余来判断一个数是奇数还是偶数。
注意,为什么快速幂的指数用 long 类型?
因为int范围是[-231,2^31-1],负数的表示范围比正数大,所以不能简单取绝对值。如果底数正好是-231,而指数是 int 类型,则会溢出。
class Solution {
private int mod = 1000000007;
public int cuttingRope(int n) {
if (n <= 3) {
return n - 1;
}
int quotient = n / 3;
int remainder = n % 3;
if (remainder == 0) {
return (int)quickPow(3, quotient);
} else if (remainder == 1) {
return (int)(quickPow(3, quotient - 1) * 4 % mod);
} else {
return (int)(quickPow(3, quotient) * 2 % mod);
}
}
//快速幂模板, 注意指数 exponent 是 long 类型防止溢出,且为非负数
public long quickPow(long base, long exponent) {
if (exponent == 0) return 1;
if (exponent == 1) return base;
long res = quickPow(base, exponent >> 1);
res = (res * res) % mod;
//如果是奇数,则要额外乘上base
if ((exponent & 0x01) == 1)
res = (res * base) % mod;
return res;
}
}