【LeetCode & 剑指offer刷题】分治法题1:16 数值的整数次方(50. Pow(x, n))

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

50. Pow(x, n)

Implement   pow( x ,   n ) , which calculates  x   raised to the power   n   (x n ).
Example 1:
Input: 2.00000, 10
Output: 1024.00000
Example 2:
Input: 2.10000, 3
Output: 9.26100
Example 3:
Input: 2.00000, -2
Output: 0.25000
Explanation: 2 -2 = 1/2 2 = 1/4 = 0.25
Note:
  • -100.0 <  x  < 100.0
  • n  is a 32-bit signed integer, within the range [−2 31 , 2 31  − 1]
 
//问题:实现求x^n
// 递归法 掌握
x^n = x^(n/2) *  x^(n/2)  ,n为偶数
       =  x^(n/2) * x^(n/2) * x, n为奇数时(假设这里的n/2已向下取整)
例子:
pow(x,10) -> pow(x,5) -> pow(x,2) -> ...
/*
分治法
O(logn)
*/
class Solution
{
public :
     double myPow ( double x , int n )
     {
         if ( n < 0 ) return 1.0 / power ( x , - n ); // 负次幂的处理
         else return power ( x , n );
     }
private :
     double power ( double x , int n )
     {
         if ( n == 0 ) return 1 ;
        
         double res = power ( x , n / 2 ); // 分解, n/2 为隐式向下取整
         if ( n % 2 == 0 )
             return res * res ; // 偶数时
         else
             return res * res * x ; // 奇数时
     }
};
 
 
//迭代法
class Solution
{
public :
    double myPow ( double x , int n )
    {
        if ( n == 0 ) return 1 ;
       
        unsigned int p ;
        if ( n < 0 ) //负数时
        {
            p =- n ;   //这里需用比n范围大的数存储,因为如果用n存在问题:n = -2147483648时会溢出
            x = 1 / x ;
        }
        else p = n ;
       
        double ans = 1 ;
        while ( p > 0 )
        {
             if(p%2 == 1) ans *= x; //p为奇数时执行此句子
            x*=x;
            p /= 2;
        }
        return ans ;
    }
};
/*
过程举例:
p
10:x = xprev^2  n = 5
5:ans = xprev^2; x = xprev^4  n = 2
2:x = xprev^8  n = 1
1:ans = xprev^2 * xprev^8  n = 0 退出循环
 
10转为二进制为1010,10 = 8 + 2,x^2*x^8即可,二进制中为1的地方就是p除以2为奇数的地方 
2L10 0
 2L5  1
  2L2 0
   1
*/
 
 
 

猜你喜欢

转载自www.cnblogs.com/wikiwen/p/10229475.html
今日推荐