zoukankan      html  css  js  c++  java
  • leetcode Pow(doubule x,int n)

    今天第一天开通博客,心情还是小激动的

    上代码:

    方法一:常规递归,x的n次方={xn/2*xn/2              //n为偶

                                                      xn/2*xn/2 *x          //n为奇数

                                                    }

     1 class Solution {
     2 public:
     3     bool isinvalid=false;                 //全局标记,标记是否是非法
     4     double pow(double x, int n) {
     5         if(((x-0.0)>-0.0000001&&(x-0.0)<0.0000001)&&n<0)   //注意,这里是比较x是否为零,网上多数没有该功能,o的负数次方,显然不行
     6         {
     7             isinvalid=true;
     8             return 0.0;
     9         }
    10         
    11         if(n==0)  return 1.0;                             //0 次方为1
    12                                     
    13         if(n<0)
    14         {
    15             return 1.0/recuryPow(x,-n);                //为什么这里的INT_MIN就没问题呢,这里没问题,是因为-n后其实还是个负数,传过去个负数
    16         }
    17         else
    18         {
    19             return recuryPow(x,n);
    20         }
    21     }
    22     double recuryPow(double x,int n)                   //这时当上面传过来是INT_MIN加负号传过来的时候,n还是INT_MIN,因为INT_MAX装不下,n还是负数为INT_MIN                   
    23     {
    24         if(n==0)
    25         {
    26             return 1.0;
    27         }
    28         if(n==1)                              //如果n为负,就不会走n==1,只可能n=-1,但是如果n=-1,后面recuryPow(x,-1)就等于1.0,然后因为-1为奇数,所以也相当于反回了x
    29         {
    30             return x;
    31         }
    32         double a=recuryPow(x,n/2);
    33         if(n&1)                                      //为奇数,无所谓正负,也可以n%2求余,负数也可以用该方法判断奇数偶数
    34         {
    35             return a*a*x;
    36         }
    37         else
    38         {
    39             return a*a;
    40         }
    41     }
    42 };

    方法二:除了上述方法,这里还提到了一种十分巧妙并且快速的方法,原文描述如下(效率快来很多):

    Consider the binary representation of n. For example, if it is "10001011", then x^n = x^(1+2+8+128) = x^1 * x^2 * x^8 * x^128. Thus, we don't want to loop n times to calculate x^n. To speed up, we loop through each bit, if the i-th bit is 1, then we add x^(1 << i) to the result. Since (1 << i) is a power of 2, x^(1<<(i+1)) = square(x^(1<<i)). The loop executes for a maximum of log(n) times.

    该方法通过扫描n的二进制表示形式里不同位置上的1,来计算x的幂次

    确实很巧妙

    为了正确计算x的n次幂,还需要考虑到以下一些情况:

    1) x取值为0时,0的正数次幂是1,而负数次幂是没有意义的;判断x是否等于0不能直接用“==”。

    2) 对于n取值INT_MIN时,-n并不是INT_MAX,这时需要格外小心。(前面用的)

    3) 尽量使用移位运算来代替除法运算,加快算法执行的速度。

    代码实现:

     1 double my_pow(double x, int n)  
     2 {  
     3     if(n==0)  
     4             return 1.0;  
     5     if(n<0)  
     6         return 1.0 / pow(x,-n);  
     7     double ans = 1.0 ;  
     8     for(; n>0; x *= x, n>>=1)  
     9     {  
    10         if(n&1>0)  
    11             ans *= x;  
    12     }  
    13     return ans;  
    14 }  

    我的代码实现

     1 class Solution {
     2 public:
     3     bool isinvalid=false;
     4     double pow(double x, int n) {
     5         if(((x-0.0)>-0.0000001&&(x-0.0)<0.0000001)&&n<0)   //x==0 case
     6         {
     7             isinvalid=true;
     8             return 0.0;
     9         }
    10         
    11         if(n==0)  return 1.0;                             //0 ci fang dengyu 1
    12         double result=1.0;                                    //fang hui de ke neng chaoguo double 
    13         
    14         if(n<0) 
    15         {
    16             if(n==INT_MIN)                             //这里很有意思,因为最小负数变成正数比最大正整数还大一,所以要单独处理
    17             {
    18                 return 1.0/(myPow(x,INT_MAX)*x);              
    19             }
    20             else
    21             return 1.0/myPow(x,-n);
    22         }
    23         else
    24         {
    25             return myPow(x,n);
    26         }
    27     }
    28     double myPow(double x,int n)                   //变成只处理n大于0的情况,如果上面传过来个负数,while那就成死循环了
    29     {
    30        double result=1.0;
    31        while(n)
    32        {
    33            if(n&1)                                //这里是看每一位是否为1,而不是看是奇偶
    34            {
    35                result*=x;
    36            }
    37            n=n>>1;                            //就算改为n/2表示右移,这里n就可以为负,但上面不行
    38            x=x*x;                             //100010  x,x2,x2*x2=x4,x8,x16,x32    
    39        }
    40        return result;
    41        
    42     }
    43 };
  • 相关阅读:
    socket是什么
    0,1,2 代表标准输入、标准输出、标准错误
    认识程序的执行:从高级语言到二进制,以java为例
    97 条 Linux 运维工程师常用命令总结[转]
    rsync 参数配置说明[转]
    shell 脚本学习之内部变量
    ansible 入门学习(一)
    python 管理多版本之pyenv
    CentOS6 克 隆
    yum 本地仓库搭建
  • 原文地址:https://www.cnblogs.com/zmlctt/p/3681078.html
Copyright © 2011-2022 走看看