leetcode-69-x 的平方根(sqrt(t))-java

版权声明:此文章为许诗宇所写,如需转载,请写下转载文章的地址 https://blog.csdn.net/xushiyu1996818/article/details/86621982

题目及测试

package pid069;
/*x 的平方根

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2

示例 2:

输入: 8
输出: 2
说明: 8 的平方根是 2.82842..., 
     由于返回类型是整数,小数部分将被舍去。


*/
public class main {
	
	public static void main(String[] args) {
		int[] testTable = {2147395599,9,4};
		for (int i=0;i<testTable.length;i++) {
			test(testTable[i]);
		}
	}
		 
	private static void test(int ito) {
		Solution solution = new Solution();
		int rtn;
		long begin = System.currentTimeMillis();
		System.out.println(ito);		
		rtn = solution.mySqrt(ito);//执行程序
		long end = System.currentTimeMillis();				
		System.out.println(rtn);
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,43ms,较快)

首先先声明,举例,一个数字为100,200,3000,长度为3,4,他们的平方根在10-99之间,即长度为2,可以得到平方根长度为(length+1)/2
所以可以得到一个数字的平方根上下限的100,1000,然后使用二分查找得到对应的平方根。
注意:是平方根的话,是if(x>=mid*mid&&x<(mid+1)*(mid+1))  在一个区间内

二分查找的话,能够改进的就是初始上下限的问题,设置上限作用较大(位数少了一半),设置下限作用较小,但是也还不错,是优化

package pid069;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Solution {
public int mySqrt(int x) {
    int length=String.valueOf(x).length();
    //10000(5 100) 100(3 10) 100-9999 (3-4 10-99) 10000-999999(5-6 100-999)
    int sqrtLength=(length+1)/2;
    double begin=(int)Math.pow(10, sqrtLength-1);
    double end=(int)Math.pow(10, sqrtLength);
    
    if(x==(begin*begin)){
    	return (int)begin;
    }
    if(x>=(end*end)){
    	return (int)end;
    }
    while(true){
    	double mid=(double)(int)((begin+end)/2);
    	if(x>=mid*mid&&x<(mid+1)*(mid+1)){
    		return (int)mid;
    	}
    	if(x>=(mid+1)*(mid+1)){
    		begin=mid+1;
    	}
    	else{
    		end=mid-1;
    	}
    }
    
    }
}

解法2(别人的)

这个题目的本质是让你求平方根,比如求x^2=t ,我们可以设一个函数f(x)=x^2- t  ,令f(x)=0,很明显解x就是t的平方根,在图里表示为与X轴的交点横坐标。而我们要做的就是求出这个交点,手段是取图像上一个初始点(t,f(t)),作它的切线,切线与X轴交点横坐标为X0,接下来我们又作(X0,f(X0))的切线,有没有发现,我们作的切线再逐渐向左偏,切线与X轴的交点也慢慢接近图像与X轴的交点,一直重复以上作切线过程,最后它们会无限逼近,到最后f(Xn)近似等于0(i从0到n),那么我们就可以认为Xn就是要求的平方根。

平方根的具体过程如下:

1、题目要求的是x的平方根,所以t =x,同时我们假设x0开始等于x;

2、如上图所示,过点(x0,f(x0))做曲线的切线 ,切线方程是y1-f( x0 )=f(x0)' ( x1 - x0 ) - t,令y1=0,解得x1=x0 / 2+t / (2*x0)

3、接下来重复2,即过点(x1,f(x1))做曲线的切线,切线方程是y2-f(x1)=f(x1)'(x2-x1) - t ,令y2=0,解得x2=x1 / 2 +t /(2*x1)

       接着重复2,一直到 f(xn) 趋向于0,而f(xn)=xn^2-t=0,所以最后近似解就是xn   

 class Solution {//牛顿迭代法,f(x)=x^2-t
        public int mySqrt(int x) {
            double t=(double)x;//(double)可以省
            double x0=x;
            x0=x0/2+t/(2*x0);
            while(Math.abs(x0*x0-t)>0.00001)
                x0=x0/2+t/(2*x0);
            return (int)x0;//double 转int类型必须使用强制类型转化
        }
    }

 

猜你喜欢

转载自blog.csdn.net/xushiyu1996818/article/details/86621982