zoukankan      html  css  js  c++  java
  • [LeetCode#50] Pow(x, n)

    Problem:

    Implement pow(xn).

    Analysis:

    This problem inherently is very easy and simple.
    Don't try to treat a problem as difficult problem, even the mysterious power operation in mathmatics, could be so easily and elegnatly sovled through algorithm. 
    
    Soltuion 1.
    The instant idea is to multiple x one by one until n times. The time complexity of such solution is O(n), which is unacceptable!
    Naive way:
    public class Solution {
        public double myPow(double x, int n) {
            if (n == 0)
                return 1;
            double res = 1;
            while (n > 0) {
                res = res * x;
                n--;
            }
            return res;
        }
    }
    
    Time Limit exceeded:
    Last executed input:
    0.00001, 2147483647
    
    Besides the expensive time cost, there is still a problem with above solution : it could not handle when n is negative. 
    
    
    Solution 2: (Recursive way)
    Since x^4 = x^2 * x^2, apparently, the computational process has a very good recursive characteristic. 
    Why not we do it through recursive way???
    
    Idea: we divide x^n into two parts. but note the n is an odd or even. 
    iff n == odd,  x^n = x^(n/2) * x^(n/2) * x;
    iff n == even, x^n = x^(n/2) * x^(n/2);
    
    public class Solution {
        public double myPow(double x, int n) {
            if (n == 1)
                return x;
            double half = myPow(x, n / 2);
            if (n % 2 == 0) {
                return half * half;
            } else {
                return half * half * x;
            }
        }
    }
    
    The above soltuion seems right, but it still have following pitfalls.
    1. cannot handle negative "n".
    the myPow fuction is based on the assumption: n is positive.
    Fix: mathematical skills.
    a^n = (1/a)^(-n)
    
    if (n > 0)
        return power(x, n);
    else
        return power(1/x, n);
        
        
    2. basecase "if (n == 1)" is not useful when n is negative!!! 
    it could incure infinite recursive call.
    Runtime Error Message:
    Line 88: java.lang.StackOverflowError
    Last executed input:
    34.00515, -3
    
    
    Because that reason, can we gurantee the passed in n is positive only?    
    
    Solution 3: 
    public class Solution {
        public double myPow(double x, int n) {
            if (x == 0)
                return 0;
            if (n == 0)
                return 1;
            if (n > 0)
                return power(x, n);
            else
                return power(1/x, -1 * n);
        }
    
        public double power(double x, int n) {
            if (n == 1)
                return x;
            ...
        }
    }
    
    The above solution wroks for most case, except when n = Integer.MIN_VAULE = -2147483648
    ----------------------------------------------------------------------------------------
    Runtime Error Message:
    Line 91: java.lang.StackOverflowError
    Last executed input:
    1.00000, -2147483648
    ********************************
    -1 * n could cause overflow!!!
    Apparently, the valid input range is [2147483647, -2147483648].
    We must take care of all possible input!
    
    Actually, we just need to make a little change over the code.
     public double myPow(double x, int n) {
            ...
            if (n > 0)
                return power(x, n);
            else
                return power(1/x, n);
        }
        
        
        public double power(double x, int n) {
            if (n == 0)
                return 1;
            ...
        }
    
    not covert n into positive(overflow)!!!
    This should be a cautious case all the time!!! never try to covert a negative number into positive number, it could cause overflow problem. 
    
    The base case if (n == 0) is perfect!!!
    Thus, during the recursive process, we don't need to care about whether the n is positive and negative, we just care when it would be rounded into 0. (we only care about times, rather than the n's value)
    
    Use "0" as base case is really an art!
    It's equal to:
    public double power(double x, int n) {
        if (n == 1 || n == -1)
            return x;
        ...
    }

    Solution:

    public class Solution {
        public double myPow(double x, int n) {
            if (x == 0)
                return 0;
            if (n == 0)
                return 1;
            if (n > 0)
                return power(x, n);
            else
                return power(1/x, n);
        }
        
        
        public double power(double x, int n) {
            if (n == 0)
                return 1;
     
            double half = power(x, n / 2);
     
            if (n % 2 == 0) {
                return half * half;
            } else {
                return half * half * x;
            }
        }
    }
  • 相关阅读:
    将Python脚本变为命令行--click模块使用
    MongoDB大批量读写数据优化记录
    [转]MongoDB更新操作replaceOne()实例讲解
    pip 18.1: pipenv graph results in ImportError: cannot import name 'get_installed_distributions'
    mitmdump 屏蔽443错误
    python3 操作appium
    appium-Could not obtain screenshot: [object Object]
    scrapy主动触发关闭爬虫
    匿名函数
    装饰器1、无参数的装饰器 2、有参数的装饰器 3、装饰器本身带参数的以及如果函数带return结果的情况
  • 原文地址:https://www.cnblogs.com/airwindow/p/4777395.html
Copyright © 2011-2022 走看看