【经典算法题】Pow(x, n)
Leetcode 0050 Pow(x, n)
分析
-
本题的考点:快速幂。
-
关于快速幂的讲解可以参考:快速幂。
-
如果
n
是正数,可以直接使用快速幂;如果n
是负数的话,我们可以对n
取绝对值变成正数,然后快速幂,最后结果取个倒数即可。 -
这里需要使用
long long
,因为当n=-2147483648
时取绝对值会溢出,溢出后的值仍然是-2147483648
,因此相当于abs(INT_MIN)==INT_MIN
。
代码
- C++
class Solution {
public:
double myPow(double x, int n) {
typedef long long LL;
bool is_minus = n < 0;
double res = 1;
for (LL k = abs(LL(n)); k; k >>= 1) {
if (k & 1) res *= x;
x *= x;
}
if (is_minus) res = 1 / res;
return res;
}
};
- Java
class Solution {
public double myPow(double x, int n) {
boolean is_minus = n < 0;
double res = 1;
for (long k = Math.abs((long)n); k > 0; k >>= 1) {
if ((k & 1) == 1) res *= x;
x *= x;
}
if (is_minus) res = 1 / res;
return res;
}
}
- Python
class Solution:
def myPow(self, x: float, n: int) -> float:
is_minus = n < 0
k = abs(n)
res = 1
while k > 0:
if (k & 1) == 1:
res *= x
x *= x
k >>= 1
if is_minus:
res = 1 / res
return res
时空复杂度分析
-
时间复杂度: O ( l o g n ) O(log n) O(logn)。
-
空间复杂度: O ( 1 ) O(1) O(1)。
类似的题目
Leetcode 0372 超级次方
题目描述:Leetcode 0372 超级次方
分析
-
本题的考点:快速幂。
-
本题要求解的是:
a b 0 b 1 . . . b n − 1 ‾ % p a^{\overline {b_0 b_1 ...b_{n-1}}} \% p ab0b1...bn−1%p
- 我们对上式进行变形:
a b 0 b 1 . . . b n − 1 ‾ % p = a b 0 b 1 . . . b n − 2 ‾ × 10 + b k − 1 % p = ( a b 0 b 1 . . . b n − 2 ‾ ) 10 × a b k − 1 % p a^{\overline {b_0 b_1 ...b_{n-1}}} \% p = a^{\overline {b_0 b_1 ...b_{n-2}} \times 10 + b_{k-1}} \% p \\ = (a^{\overline {b_0 b_1 ...b_{n-2}}})^{10} \times a^{b_{k-1}} \% p ab0b1...bn−1%p=ab0b1...bn−2×10+bk−1%p=(ab0b1...bn−2)10×abk−1%p
- 我们可以看到我们将原问题转化成了更小的子问题,因此可以递归求解。
代码
- C++
class Solution {
public:
const int p = 1337;
// 返回a ^ b % p
int qmi(int a, int b) {
a %= p;
int res = 1;
while (b) {
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
int superPow(int a, vector<int>& b) {
if (b.empty()) return 1;
int k = b.back();
b.pop_back();
return qmi(superPow(a, b), 10) * qmi(a, k) % p;
}
};
- Java
class Solution {
static final int p = 1337;
int index; // 当前遍历到b中的哪个元素
public int superPow(int a, int[] b) {
index = b.length - 1;
return pow(a, b);
}
private int pow(int a, int[] b) {
if (index < 0) return 1;
int k = b[index--];
return qmi(pow(a, b), 10) * qmi(a, k) % p;
}
// 返回a ^ b % p
private int qmi(int a, int b) {
a %= p;
int res = 1;
while (b != 0) {
if ((b & 1) == 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
}
时空复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),
n
为数组b
的长度。 -
空间复杂度: O ( n ) O(n) O(n)。