数值的整数次方(剑指offer 16)Java快速幂

简介: 实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。

一、题目描述



实现 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/22 = 1/4 = 0.25

 

提示:

-100.0 < x < 100.0

-231 <= n <= 231-1

-104 <= xn <= 104


二、思路讲解


       

首先先尝试了一下for循环暴力,超时。

       

然后试了一下两个头尾指针二分,超时。

       

然后就想到,可不可以让幂每次减半呢?(因为对于for循环来说,幂就代表着次数,幂减半,时间复杂度就可以降到logn了)。


当幂减半的时候,底数应该加倍。比如:2^10 = 4^5,原本需要遍历10次的,现在遍历5次就行了。

       

当然,这里也是要分奇偶性的:

     

1、当n为偶数时:x^n = x平方^(n/2);


2、当n为奇数时:x^n = x平方^(n/2) * x;(幂整除2之后,还要多乘一项)


     

我们就可以这样一直二分下去,当幂为0时,乘数就是我们要的结果了。举个例子:


2^10 = 4^5 = (4^2)^2 * 4 = (16^2)^1 * 4 = 1024^0 = 1024


三、Java代码实现



class Solution {
    public double myPow(double x, int n) {
        //当n为-2147483648时,n=-n会出现越界错误,所以用long
        long nn = n;
        boolean fu = false; //用来标记n是否为负数
        if(nn == 0 || x==1.0){  //如果是0次幂或者底数为1(其实不需要判断,也可以通过)
            return 1;
        } else if(nn < 0){  //如果幂为负数
            fu = true;
            nn = -nn;
        }
        if(x == 0){ //如果底数为0
            return 0;
        }        
        double res = 1;
        //将幂一直二分
        while(nn > 0){
            if(nn%2 != 0){
                res = res * x;
            }
            //幂二分,底数就应该翻倍
            x = x * x;
            nn = nn / 2;
        }
        if(fu){ //如果是幂是负数,取倒数
            res = 1 / res;
        }
        return res;
    }
}



四、时空复杂度分析



时间复杂度:        O(logn)        n为幂


空间复杂度:        O(1)


五、另一种方法



有迭代自然有递归。


相关文章
|
2月前
|
Java
java基础(10)数据类型中的整数类型
Java中的整数类型包括byte、short、int和long。整数字面值默认为int类型,加L表示long类型。整数字面值可以是十进制、八进制(0开头)或十六进制(0x开头)。小容量类型(如int)可自动转换为大容量类型(如long),但大容量转小容量需强制转换,可能导致精度损失。
39 2
|
5月前
|
Java 程序员
程序员必知:【java】判断字符串是否整数的三种方式,孰优孰劣请自行判断
程序员必知:【java】判断字符串是否整数的三种方式,孰优孰劣请自行判断
169 3
|
5月前
|
Java
剑指offer_3_前n个数字二进制形式中1的个数(java)
剑指offer_3_前n个数字二进制形式中1的个数(java)
|
5月前
|
Java
剑指offer_2_二进制加法(java)
剑指offer_2_二进制加法(java)
|
5月前
|
Java
剑指offer_1_整数除法(java)
剑指offer_1_整数除法(java)
|
6月前
|
存储 安全 Java
剑指offer全集系列Java版本(2)
剑指offer全集系列Java版本(2)
34 0
|
6月前
|
存储 Java
剑指offer全集系列Java版本(1)
剑指offer全集系列Java版本(1)
42 0
|
6月前
|
算法 Java C++
刷题两个月,从入门到字节跳动offer丨GitHub标星16k+,美团Java面试题
刷题两个月,从入门到字节跳动offer丨GitHub标星16k+,美团Java面试题
|
6月前
|
Java
JAVA输入任意一个数字,实现递减求和(计算任意整数n的和)
JAVA输入任意一个数字,实现递减求和(计算任意整数n的和)
58 0
ZZULIOJ-1111: 多个整数的逆序输出(函数专题)(Java)
ZZULIOJ-1111: 多个整数的逆序输出(函数专题)(Java)