剑指Offer_编程题——数值的整数次方
题目描述:
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。保证base和exponent不同时为0
具体要求:
时间限制: C/C++ 1秒,其他语言2秒
空间限制: C/C++32M,其他语言64M
具体思路:
思路一:
其实是一种最简单最暴力的算法,也不用考虑任何条件,直接根据数学知识即可解决,即用python实习如下:
class Solution:
def Power(self, base, exponent):
return base ** exponent
代码效果图如图所示:
思路二:
其实利用左移和右移即可实现,因此我们介绍左移和右移的计算过程。
1、<<:左移运算符,num << 1, 相当于num乘以2
2、>>:右移运算符,num >> 1,相当于num除以2
3、>>>:无符号右移符,忽略符号位,空位都以0补齐(负数用1补齐)
接下来介绍介绍一种新型的判断奇偶数的方法:
众所周知,我们一般判断奇偶数就是用这个数对2取模,如果为0则为偶数,否则为奇数。这种方法符合我们的日常思维,但是运行时间较慢。另一种方法就是用二进制中的“与”运算符。用a&1来判断a的奇偶性。二进制的末尾为0表示偶数,末尾为1则是奇数。
具体用java来实现这一思路:
public class Solution{
public double Power(double base, int exponent){
if(exponent < 0 && base == 0)throw new RuntimeException("分母不能为0");
int exp = Math.abs(exponent);
if(exponent == 0)
return 1;
if(exponent == 1)
return base;
double result = Power(base, exp >>> 1);
result *= result;
if((exp & 1) == 1){
result *= base;
}
return exponent < 0 ? (1.0 / result) : result;
}
}
代码效果图如图所示:
如果我们要在编译器中运行,得添加上main()即可;具体实现如下:
public static void main(String[] args){
Solution s1 = new Solution();
System.out.println(s1.Power(5.0, 3));
}
代码在编译器测试效果如下:
思路三:
可以使用迭代去做。根据题意可知,exponent是整数。因此我们这里需要考虑exponent是0或者负数的情况:
1、当exponent是正数时,按照我们正常的迭代计算即可
2、当exponent是0时,直接返回0即可
3、当exponent是负数时,可以先求出其绝对值的结果,再取倒数
class Solution:
def Power(self, base, exponent):
if exponent < 1:
return 1 / self.getPower(base, -exponent)
else:
return self.getPower(base, exponent)
def getPower(self, base, exponent):
if base == 0:
return 0
elif exponent == 1:
return base
res = 1
for i in range (exponent):
res *= base
return res
代码效果图如图所示:
针对思路三的想法,我们可以对exponent为正数的时候,做一个简单的优化,即我们可以使用我们熟悉的递归来高效的求出正数的整数次方,从而提高运行时间。
class Solution:
def Power(self, base, exp):
if exp < 1:
return 1 / self.getPower(base, -exp)
else:
return self.getPower(base, exp)
def getPower(self, base, exp):
if exp == 0:
return 1
elif exp == 1:
return base
res = self.Power(base, exp >> 1)
res *= res
if exp & 1 == 1:
res *= base
return res
代码效果图如图所示:
总结
本道题主要通过求指数来考察用代码实现计算,本文中运用了各种思路,其中包括我们这几天一直用的递归算法。当然,在本文中我们还介绍了左移和右移的原则以及介绍了一种全新的判断一个数奇偶性的方法,发现运行时间提高了不少。在做完题目之后,我们应该擅于总结,吸取别人做的好的思路,不断的提高自己的思路,提高自己分析问题的思路和写代码的能力。总之,继续加油,争取早日找到工作,Good Luck!!!
参考文献
本文主要参考以下资料:
[1]脑图思考
[2]负雪明烛