Offer[16] 数值的整数次方

Posted haoworld

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Offer[16] 数值的整数次方相关的知识,希望对你有一定的参考价值。

题目描述

  实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
  

思路分析

  1. 要考虑到指数为负数的情况,而且指数为负数的时 base不能为0,因为指数为负数时,是指数的绝对值次幂的倒数,(分母不能为0),考虑到这些情况之后,就可以转化为求exponent的绝对值 次幂的问题,即指数为正数的情况
  2. 现在考虑如何求数值的整数次幂(指数为正数的情况):

    • 一种方法是直接求,循环exponent次 求得exponent个base的乘积,
    • 第二种巧妙的方法,可以利用斐波那契数列的思想,这里利用递归方法,

      • 当指数为偶数时:可以表示成 两个 baseex/2 次幂 的乘积
      • 奇数时:可以表示成 两个 baseex/2 次幂 乘积 再乘以base(这里的ex/2是在程序中的运算,5/2 = 2
      • 公式如下:

      技术图片
      ?

测试用例

  指数和底数都分别设置为正数、负数和0.

Java代码

public class Offer16 

    public static void main(String[] args) 
        test1();
        test2();
        test3();
    

    public static double powCustom(double base, int exponent) 
        return Solution2(base, exponent);
    

    /**
     * 解法一, 要考虑到边界值, exponent为负数时,还要比如0的负数次方
     * 
     * 其中powCustomCore1 方法是利用 直接求的方法
     * 
     * @param base
     * @param exponent
     * @return
     */
    private static double Solution1(double base, int exponent) 
        if (base == 0 && exponent < 0) 
            throw new IllegalArgumentException("0的指数不能为负数");
        
        int absExponent = exponent;
        if (exponent < 0) 
            absExponent = -exponent;
        
        double result = powCustomCore1(base, absExponent);
        if (exponent < 0) 
            result = 1.0 / result;
        
        return result;
    

    /**
     * 方法一: 直接求,将exponent个 base 相乘
     * 
     * @param base     基数
     * @param exponent 指数
     * @return
     */
    private static double powCustomCore1(double base, int exponent) 
        double result = 1.0;
        for (int i = 1; i <= exponent; i++) 
            result *= base;
        
        return result;
    

    /**
     * 解法二, 要考虑到边界值, exponent为负数时,还要比如0的负数次方
     * 
     * 其中 powCustomCore2 方法是利用 递归的方法
     * 
     * @param base
     * @param exponent
     * @return
     */
    private static double Solution2(double base, int exponent) 
        if (base == 0 && exponent < 0) 
            throw new IllegalArgumentException("0的指数不能为负数!");
        
        int absExponent = exponent;
        if (exponent < 0) 
            absExponent = -exponent;
        
        double result = powCustomCore2(base, absExponent);
        if (exponent < 0) 
            result = 1.0 / result;
        
        return result;
    

    /**
     * 方法二:
     * 
     * exponent为偶数时,可以将其简化为 两个base的 ex/2 次幂 相乘 exponent为奇数时,可以将其简化为,两个base的 ex/2 次幂
     * 相乘之后再乘以base
     * 
     * @param base     基数
     * @param exponent 指数
     * @return
     */
    private static double powCustomCore2(double base, int exponent) 
        if (exponent == 0) 
            return 0;
        
        if (exponent == 1) 
            return base;
        
        double result = powCustomCore2(base, exponent >> 1);
        result *= result;
        if ((exponent & 1) == 1) 
            result *= base;
        
        return result;
    

    private static void test1() 
        System.out.println("3,3---->" + powCustom(3, 3));
    

    private static void test2() 
        System.out.println("3,-3----->" + powCustom(3, -3));
    

    private static void test3() 
        System.out.println("-3,3------>" + powCustom(-3, 3));
    

代码链接

剑指Offer代码-Java

以上是关于Offer[16] 数值的整数次方的主要内容,如果未能解决你的问题,请参考以下文章

数值的整数次方(剑指offer_16)

刷题记录-剑指offer16:数值的整数次方

刷题记录-剑指offer16:数值的整数次方

剑指Offer面试题16. 数值的整数次方

剑指Offer面试题16. 数值的整数次方

LeetCode(剑指 Offer)- 16. 数值的整数次方