50. Pow(x, n)
Problem¶
Implement pow(x, n), which calculates x
raised to the power n
(i.e., xn
).
Example 1:
Input: x = 2.00000, n = 10
Output: 1024.00000
Example 2:
Input: x = 2.10000, n = 3
Output: 9.26100
Example 3:
Input: x = 2.00000, n = -2
Output: 0.25000
Explanation: 2-2 = 1/22 = 1/4 = 0.25
Constraints:
-100.0 < x < 100.0
-231 <= n <= 231-1
n
is an integer.- Either
x
is not zero orn > 0
. -10**4 <= xn <= 10**4
Solve¶
Use built-in function¶
O(log n)
Actually doing some thing¶
Basically, we can use the following recursive formula to calculate x^n
efficiently:
pow(x,n) = pow(x,n/2) * pow(x,n/2) * pow(x,n%2)
python¶
O(log n)
There isn’t anything stop python from working
- Implement the function directly using recursion
-
Case n < 0: we just need to change our
x = 1/x
and can safely clearn
sign; Keep in mind that when x == 0, this can throw error.
-
The above code could re-calculate some
pow()
, to avoiding this, we can add acache
array.
class Solution: def myPow(self, x: float, n: int, cache = None) -> float: if x == 0.: return 0 if cache is None: cache = {} cache[0] = 1. cache[1] = x if x != 0: cache[-1] = 1./x if n in cache: return cache[n] cache[n] = self.myPow(x, n//2, cache) * self.myPow(x, n//2, cache)* self.myPow(x, n%2, cache) return cache[n]
C language¶
O(1)
Using the same logic, but there is some thing to consider:
- We can’t just revert the sign of a number, as
int
value have 32 bit, whichMAX_INT == 2**31
andMIN_INT == 2**31 - 1
(because of0
) - C not have
dict()
by default and we also don’t want to create a large[-2*32..2*32-1]
array. While this can be overcome with Hash functions, we can store only[x**(2**0), x**(2**1), ..., x**(2**32)]
- A number
n
is presented using binary; which mean, by using bit manipulation, we can easily split-edn
to sum of =(1 or 0) * 2**0 + (1 or 0) * 2**1 + ... + (1 or 0) 2 ** 32
. Leverage:x**n = x ** (<splited number which total = n>)
. We can using thisbinary
split instead of divine by 2 like python. -
Here is the Try to match Python function
double cache[32]; double myPow(double x, int n){ long tmp_n = n; if (x == 0.) return 0; if (tmp_n < 0) { tmp_n = -tmp_n; x = 1./x; } cache[0] = x; double answer = 1.; for (int i = 0; i < 32 || tmp_n > 0; i++) { bool flag = tmp_n & 1; tmp_n = tmp_n >> 1; if (i > 0) cache[i] = cache[i-1] * cache[i-1]; if (flag) answer *= cache[i]; } return answer; }
-
As we only need
cache[i-1]
, we not even needcache
in the fist place; - The way to handle n < 0 can be optimize more, instead of large the variable with 64 bit long integer.
- In C, negative number is representing in
~ <unsign> +1
, which mean flipping all bit in unsigned number and then plus1
(example0001
become1110 + 1 = 1111
) - We can use this instead of
n = -n
bit flip which could result an out of memory scope error. - We handle the separated plus
1
directly in case ofn < 0
- In C, negative number is representing in
Or this, separating n == 0; n > 0; and n < 0
also work:
double myPow(double base, int exp)
{
double result = 1;
if (base == 0) return 0;
if (exp > 0)
for (;;) {
if (exp & 1)
result *= base;
exp >>= 1;
if (!exp)
break;
base *= base;
}
else if (exp < 0) {
exp = ~(exp);
result /= base;
for (;;) {
if (exp & 1)
result /= base;
exp >>= 1;
if (!exp)
break;
base *= base;
}
}
return result;
}
Compiler optimized will help us to minimal the Assembly code in any way; Also, using C we can some how have an optimized function that can process on pair with provided standards
pow(x,n)
built-in the language, which take0ms
to run.
Time complexity:
- This cost a fixed for loop 32 times, which we can consider it as O(1) run time.
- But, we also can consider this O(log n) time, as it could be better in the second implementation.
Created : August 16, 2023