LeetCode 50 - Calculate pow(x,n)


Above function can be optimized to O(logn) by calculating power(x, y/2) only once and storing it.
int power(int x, unsigned int y)
{
    int temp;
    if( y == 0)
        return 1;
    temp = power(x, y/2);
    if (y%2 == 0)
        return temp*temp;
    else
        return x*temp*temp;

}
public double myPow(double x, int n) { if (n == 0) return 1; if (x == 1) return 1; if (x == -1) { if (n % 2 == 0) return 1; else return -1; } if (n == Integer.MIN_VALUE) return 0; if (n < 0) { n = -n; x = 1/x; } double ret = 1.0; while (n > 0) { if ((n & 1) != 0) ret *= x; x = x * x; n = n >> 1; } return ret; }
思路1:利用整数n的二进制表达
性质:(x^y)^z = x^(y*z)
例如:(5^3)^2 = 5^3 * 5^3 = 5^(3*2)

10: 二进制(1010)b = (2^3)*1 + (2^2)*0 + (2^1)*1 + (2^0)*0
3^10 = 3^[(2^3)*1] * 3^[(2^2)*0] * 3^[(2^1)*1] * 3^[(2^0)*0] 
res = 1
res = res^2 * 3^1 = 3^(1)b
res = res^2 * 3^0 = 3^2 = 3^(10)b
res = res^2 * 3^1 = 3^5 = 3^(101)b
res = res^2 * 3^0 = 3^10 = 3^(1010)b
需要特殊处理 n<0的情况。
    double pow(double x, int n) {
        bool negPow = n<0 ? true : false;
        n = abs(n);
        double res = 1;
        for(int i=31; i>=0; i--) {
            res = res*res;
            if(n & (1<<i))
                res = res*x;
        }
        if(negPow) res = 1/res;
        return res;
    }


    double pow(double x, int n) {
        if(n>=0)
            return powPositive(x,n);
        else
            return 1/powPositive(x,-n);
    }
    
    double powPositive(double x, int n) {
        if(n==0) return 1; // base case
        double res = powPositive(x, n/2);
        res *= res;
        if(n%2) res *= x;
        return res;
    }
http://www.sigmainfy.com/blog/leetcode-powx-n.html
double bs(double x, int n) {
    if (n == 0) return 1;
    double ret = bs(x, n / 2);
    if (n & 1) 
        return ret * ret * x; 
    else 
        return ret * ret; 
}

double pow(double x, int n) {
    if (abs(x) <= eps) return 0.0;
    if (0 == n) return 1.0;
    if (abs(abs(x) - 1.0) <= eps) {
          if (n & 1) return x;
          else 
              return 1.0;
    }
    double ret = x;
    bool negative = n < 0;
    n = abs(n);
    ret = bs(x, n);    
    if (negative) return 1.0 / ret;
    return ret;
}
  1. use |val – 0.0| < eps to test if the base x is equal to zero or not instead of using x == 0
https://leetcode.com/discuss/52800/5-different-choices-when-talk-with-interviewers

1. nest myPow

double myPow(double x, int n) {
    if(n<0) return 1/x * myPow(1/x, -(n+1));
    if(n==0) return 1;
    if(n==2) return x*x;
    if(n%2==0) return myPow( myPow(x, n/2), 2);
    else return x*myPow( myPow(x, n/2), 2);
}

2. double myPow

double myPow(double x, int n) { 
    if(n==0) return 1;
    double t = myPow(x,n/2);
    if(n%2) return n<0 ? 1/x*t*t : x*t*t;
    else return t*t;
}

3. double x

double myPow(double x, int n) { 
    if(n==0) return 1;
    if(n<0){
        n = -n;
        x = 1/x;
    }
    return n%2==0 ? myPow(x*x, n/2) : x*myPow(x*x, n/2);
}

4. iterative one

double myPow(double x, int n) { 
    if(n==0) return 1;
    if(n<0) {
        n = -n;
        x = 1/x;
    }
    double ans = 1;
    while(n>0){
        if(n&1) ans *= x;
        x *= x;
        n >>= 1;
    }
    return ans;
}

5. bit operation

https://leetcode.com/discuss/12004/my-answer-using-bit-operation-c-implementation


In bit format and for a unsigned number, the number is represented as k0*2^0 + k1*2^1 + ... +k31*2^31. Therefore, once we know the pow(x,2^0), pow(x,2^1), ..., pow(x,2^31), we can get pow(x,n). And pow(x,2^m) can be constructed easily as pow(x,2^m) = pow(x,2^(m-1)*pow(x,2^(m-1).
double pow(double x, int n) { if(n<0){ x = 1.0/x; n = -n; } int unsigned m = n; double tbl[32] = {0}; double result = 1; tbl[0] = x; for(int i=1;i<32;i++){ tbl[i] = tbl[i-1]*tbl[i-1]; } for(int i=0;i<32;i++){ if( m & (0x1<<i) ) result *= tbl[i]; } return result; }
https://leetcode.com/discuss/17005/short-and-easy-to-understand-solution
public double pow(double x, int n) { if(n == 0) return 1; if(n<0){ n = -n; x = 1/x; } return (n%2 == 0) ? pow(x*x, n/2) : x*pow(x*x, n/2); }
should we add if(x == 0) return 0;

the type of x is double you can't use if(x==0)
//O(lgn)
public static int powRec(int x, int y){
 if(y == 0){
  return 1;
 }
 if(y == 1){
  return x;
 }
 
 int pow = powRec(x, y/2);
 if((y&1) != 0){
  return pow*pow*x;
 }
 else{
  return pow*pow;
 }
}

//O(lgn)
public static int powIter(int x, int y){
 int pow = 1;
 
 if(y == 0){
  return 1;
 }
 if(y == 1){
  return x;
 }
 
 while(y > 0){
  //if y is odd
  if((y&1) != 0){
   pow*=x;
  }
  
  //divide by 2
  y >>= 1;
  //calclate x^2
  x = x*x;
 }
 
 return pow;
}

Let us extend the pow function to work for negative y and float x.
From http://www.programcreek.com/2012/12/leetcode-powx-n/

public double power(double x, int n) {
 if (n == 0)
  return 1;
 
 double v = power(x, n / 2);
 
 if (n % 2 == 0) {
  return v * v;
 } else {
  return v * v * x;
 }
}
 
public double pow(double x, int n) {
 if (n < 0) {
  return 1 / power(x, -n);
 } else {
  return power(x, n);
 }
}

float power(float x, int y)
{
    float temp;
    if( y == 0)
       return 1;
    temp = power(x, y/2);      
    if (y%2 == 0)
        return temp*temp;
    else
    {
        if(y > 0)
            return x*temp*temp;
        else
            return (temp*temp)/x;
    }
}
http://blog.csdn.net/linhuanmars/article/details/20092829
public double pow(double x, int n) {
    if(n==0)
        return 1.0;
    double res = 1.0;   
    if(n<0)
    {
        if(x>=1.0/Double.MAX_VALUE||x<=1.0/-Double.MAX_VALUE)
            x = 1.0/x;
        else
            return Double.MAX_VALUE;
        if(n==Integer.MIN_VALUE)
        {
            res *= x;
            n++;
        }
    }
    n = Math.abs(n);
    boolean isNeg = false;
    if(n%2==1 && x<0)
    {
        isNeg = true;
    }
    x = Math.abs(x);
    while(n>0)
    {
        if((n&1) == 1)
        {
            if(res>Double.MAX_VALUE/x)
                return Double.MAX_VALUE;
            res *= x;
        }
        x *= x;
        n = n>>1;
    }
    return isNeg?-res:res;
}
以上代码中处理了很多边界情况,这也是数值计算题目比较麻烦的地方。比如一开始为了能够求倒数,我们得判断倒数是否越界,后面在求指数的过程中我们也得检查有没有越界。所以一般来说求的时候都先转换为正数,这样可以避免需要双向判断(就是根据符号做两种判断)。
接下来我们介绍二分法的解法,如同我们在Sqrt(x)的方法。不过这道题用递归来解比较容易理解,把x的n次方划分成两个x的n/2次方相乘,然后递归求解子问题,结束条件是n为0返回1。因为是对n进行二分,算法复杂度和上面方法一样,也是O(logn)。代码如下:

Also refer to http://www.programcreek.com/2012/12/leetcode-powx-n/
Read full article from Write a C program to calculate pow(x,n) | GeeksforGeeks

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts