Leetcode[二分查找] 50. Pow(x, n)

Leetcode[二分查找] 50. Pow(x, n)

审题

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例 1:
输入: 2.00000, 10
输出: 1024.00000

示例 2:
输入: 2.10000, 3
输出: 9.26100

示例 3:
输入: 2.00000, -2
输出: 0.25000
解释: 2^-2 = 1/2^2 = 1/4 = 0.25

说明:
-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1] 。

看到这道题的时候,我首先想到的是数值范围的问题,会不会还要自己实现长整数加减之类的问题…然而好像不用(用的话可真就麻烦了,长整型加减现在也不太会,以后有机会要好好实现一遍),因为double的范围还是很大的,并且测试数据也没有刻意难为我们,因此,专注于代码实现,我们实现了两种方法,暴力和分治,暴力就是纯的,一个一个乘,分治就是将例如:277变成238*238*2这种,那么思路清晰之后,我们直接看代码。

代码实现

方案一(上文提到的第一个方法(解决失败)):

这个方法想的很简单,分正负两种情况进行考虑,但是可惜的是只能过90%的测试数据,对于更多的测试数据不知道是因为精度不够还是什么原因,并不能够正确实现,还不是超时的问题。因为本身暴力就挺无聊的,我们不深究这个问题了,直接方案二。

class Solution {
public:
    double neg(double x, int n) {
        if ( n == 0 ) return 1;
        else return neg(x, n+1)/x;
    }
    double pos(double x, int n) {
        if ( x<1 && n>1000 ) return 0; 
        if ( n==1 ) return x;
        else return x*pos(x, n-1);
    }
    double myPow(double x, int n) {
        if ( n > 0 ) return pos(x, n);
        else return neg(x, n);
    }
};

方案2(分治):

看了官方题解,发现这个可以直接用一个函数进行实现,并且用了三目运算符之后的码风也是十分清晰,因此我们有了如下代码,其中需要注意两个地方:

  1. n不可以直接带入到我们自己的函数中,因为有一个-N的位置INT_MIN取负号是不可以用int表示的,因此要用到long long,不过这个是从C99才开始支持的概念,哎,既然官方题解都这么写了,那咱就也大胆用了。
  2. 对于分治,要判断是否需要多乘一个x和返回的条件。

掌握了这两点之后,我们有了如下代码。

class Solution {
public:
    double quick(double x, long long n) {
        if ( n == 0 ) return 1;
        else {
            double y = quick(x, n/2);
            return (n%2) ? y*y*x : y*y;
        }
    }
    double myPow(double x, int n) {
        long long N = n;
        return n>0 ? quick(x,N) : 1/quick(x,-N);
    }
};

反思

对于这道题,在最开始想到了暴力解法就直接上手写了,然而,事实证明这是非常不好的一个行为,因为一是即使做出来对自己的码力也没有提高,毕竟这不是比赛,二是直接写没有优化自己的算法和抠细节,也失去了很多算法的简洁度,总而言之,想好再动笔永远是没错的,就像计算机上的空间换时间云云,我们不能用体力换脑力啊,毕竟我们还是要靠脑袋吃饭的,你说对吧。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值