1. 程式人生 > >【LeetCode & 劍指offer刷題】分治法題1:16 數值的整數次方(50. Pow(x, n))

【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 */