JianZhiオファー14-II。ロープを切るII
タイトル説明
問題解決のアイデア
この質問はロープIの切断に基づいており、残りがもう1つあるため、Math.powメソッドを使用できません。指数を自分で実装する必要があります。
ここでは高速べき乗剰余が使用されており、テンプレートとして使用できます。時間はo(ログ)、スペースはo(1)です。主な最適化ポイントは、右シフト演算子を使用して除算を2に置き換え、ビット単位のAND演算子を使用して余りを置き換え、数値が奇数か偶数かを判断することです。
高速パワーの指数が長いタイプを使用するのはなぜですか?
intの範囲は[ -231,2 ^ 31-1]であるため、負の数の範囲は正の数の範囲よりも大きく、単純に絶対値を取ることはできません。底が正確に-23で、指数が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;
}
}