携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
pow(x,n)
实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,x的n次方 )。
来源:力扣(LeetCode)链接:leetcode.cn/problems/po…
分析
递归
- 计算x的n次方,属于幂运算,幂运算有这样一条法则:
(a^n)^m= a^(m*n) - 基于幂运算的基本法则,在算x的n次方的时候,可以不用x连乘n次,就大大减少了运算次数,那怎样做才是最少的次数?比较容易想到二分法+递归,每次递归n减少一半,如果n是偶数就正好是n/2次,如果是奇数,二分后再乘一次x
- 最后根据n是正数还是负数返回结果
代码
var myPow = function(x,n){
if(n == 0) {
return 1
}
if(n<0){
return myPow(1/x, -n)
}
if(n%2 === 0){
let n = myPow(x, n/2)
return n*n
} else {
let n = myPow(x, (n-1)/2)
return n*n*x
}
}
迭代
- 因为递归需要额外的栈,空间复杂度为O(logn),可以换另一种思路,使用迭代的解法
- 幂运算除了上面提到的,还有一个是
(x^m)*(x^n) = x^(m+n) - 把n拆成几个数相加,把这几个数当成x的幂,几个幂的运算结果相乘,即可得出结论
- 在拆数这部分,也不是随便拆的,计算机擅长的是二进制,这里可以把十进制n拆成几个二进制相加,即
x^n = (x^a)*(x^b)*...*(x^m),a+b+...+m = n,2^k0 = a,2^k1 = b,...,所以当[k0,k1...kx]中为0的时候,是当前结果的平方,为1的时候需要乘当前x,最后得出结果
代码
var myPow = function(x, n) {
const on = n;
let ans = 1;
n = [...Math.abs(n).toString(2)];
while(n.length) {
const instruction = n.shift();
switch(instruction) {
case "0":
ans *= ans;
break;
case "1":
ans *= ans;
ans *= x;
break;
}
}
return on < 0 ? 1/ans : ans;
};
总结
- 今天的题目难度等级为中等,主要用分治的思想,把一个问题分成2个或者多个向上的子问题,再把子问题分成更小的问题,最后得到结果
- 世界的尽头是数学,算法的尽头也是数学
- 基础的数学运算、数学方法、定理、公理常驻大脑内存,解题会更加有思路
- 今天也是有收获的一天