剑指 Offer 16. 数值的整数次方
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。
示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000
示例 2:
输入:x = 2.10000, n = 3
输出:9.26100
示例 3:
输入:x = 2.00000, n = -2
输出:0.25000
解释: 2 − 2 = 1 / 2 ∗ 2 = 1 / 4 = 0.25 2^{-2} = 1/2*2 = 1/4 = 0.25 2−2=1/2∗2=1/4=0.25
提示:
− 100.0 < x < 100.0 -100.0 < x < 100.0 −100.0<x<100.0
− 2 31 < = n < = 2 31 − 1 -2^{31} <= n <= 2^{31}-1 −231<=n<=231−1
− 1 0 4 < = x n < = 1 0 4 -10^{4} <= x^{n} <= 10^{4} −104<=xn<=104
解题思路:递归迭代+二分
递归分析:
- 如果n == 0,返回1
- 如果n < 0,最终结果为 1 / x − n 1/x^{-n} 1/x−n
- 如果n为奇数,最终结果为 x ∗ x n − 1 x * x ^ {n - 1} x∗xn−1
- 如果n为偶数,最终结果为 x 2 ∗ ( n / 2 ) x ^ {2*(n/2)} x2∗(n/2)
class Solution:
def myPow(self, x: float, n: int) -> float:
if n == 0:
return 1
elif n < 0:
return 1/self.myPow(x, -n)
elif n & 1:
return x * self.myPow(x, n - 1)
else:
return self.myPow(x*x, n // 2)
二分+迭代
- 初始化 res = 1;
- 当 n < 0时:把问题转化至 n≥0 的范围内,即执行 x = 1/x,n=−n ;
循环计算;n=0 时跳出; - 当 n&1=1 时:将当前 x 乘入 res (即 res *= x);
- 执行 x = x 2 x = x ^{2} x=x2(即 x *= x);
- 执行 n右移一位(即 n >>= 1)即二分。
- 返回 res 。
- 复杂度分析:
- 时间复杂度 O ( l o g 2 n ) O(log_{2}^{n}) O(log2n) 二分的时间复杂度为对数级别。
- 空间复杂度 O(1): res, b 等变量占用常数大小额外空间
class Solution:
def myPow(self, x: float, n: int) -> float:
res = 1
if n < 0:
x = 1 / x
n = - n
while n:
if n & 1:
res *= x
x *= x
n >>= 1
return res
1015. 可被 K 整除的最小整数
给定正整数 K,你需要找出可以被 K 整除的、仅包含数字 1 的最小正整数 N。
返回 N 的长度。如果不存在这样的 N,就返回 -1。
示例 1:
输入:1
输出:1
解释:最小的答案是 N = 1,其长度为 1。
示例 2:
输入:2
输出:-1
解释:不存在可被 2 整除的正整数 N 。
示例 3:
输入:3
输出:3
解释:最小的答案是 N = 111,其长度为 3。
提示:
1 <= K <= 10^5
class Solution:
def smallestRepunitDivByK(self, k: int) -> int:
if (k % 2 == 0 or k % 5 == 0):
return -1
length = 1
x = 1
while(x % k != 0):
x = x % k
x = x * 10 + 1
length += 1
return length