LeetCode每日一题-367.有效平方数

LeetCode每日一题--有效的完全平方数(三种方法)

2021.11.4

1.题目概述

不亏简单题,简单的表述,简单的输出

2.题目理解

在给出数字的某一个范围内,有一个数字的平方等于它

三种方法

  • 1使用库函数
  • 2.二分法求解
  • 3.使用牛顿迭代法(现学现卖)

3.解题代码

使用库函数

class Solution {
   public boolean isPerfectSquare(int num) 
    {
    	//捞的办法,使用库函数
    	double sq=Math.sqrt(num);
    	return sq-(int)sq==0;
    }
}

二分法查找

class Solution {
   public boolean isPerfectSquare(int num) 
    {
    	//不太捞的办法,创建一个100以内的小表,另外100以上就在/10的范围内二分法查找
    	int []Table=new int [10];
    	for(int i=1;i<=10;i++)
    		Table[i-1]=i*i;
    	//先对进来的数字进行检查
    	if(num>=1&&num<=100)
    	{
        	for(int i=0;i<10;i++)
        		if(num==Table[i])
        			return true;
    	}
    	//大于100的数字做/10范围的内的二分法查找
    	long left=11;
    	long right=num/10;
    	long mid=0;
    	while(left<=right)
    	{
    		mid=(right-left)/2+left;
            //System.out.println("left: "+left+" right: "+right+" "+mid+"-->"+num/mid);
    		if(mid*mid==num) return true;
    		else if(num<mid*mid ) right=mid-1;
    		else left=mid+1;
    	}
    	return false;
    }
}

​ 这个做法我还是有些说的,首先说我为什么要建立一个100内的表吧,其实是为了快速,因为sqrt(100)=10,也就是在1-10的范围内其实就可以查找到1-100内的完全平方数,而如果我一开始不建表,在二分法的时候将right=num/2,其实还是有些缓慢,在建表之后,我的写法就可以是num/10开始查找了,算是把内存和速度平均一下。

​ 一开始的时候,我没有使用long,使用的是int,但是我判断部分写的是if(num/mid==mid),但是这样会有精度问题,所以我将二分查找的数据类型换成了double ,并且在if(Math.abs(num/mid-mid)<0.01))来判断,但是由于后面对于left和right的步长是1,所以导致一直跳不到,所以后面使用了long类型,因为long的最大值2^64-1,可以避免整数溢出,但是其实这样以来在判断64位整数的时候就仍然会溢出。

牛顿迭代法

一篇介绍这个的文章:urlhttps://www.zhihu.com/question/20690553

class Solution {
   public boolean isPerfectSquare(int num) 
    {
        if(num==1) return true;
        //起始点为num的中点
    	int x=num/2;
        //50次迭代范围内
        for(int i=0;i<20;i++)
        {
            x=(x-(x-num/x)/2);
        }
        System.out.println(x+"  -> "+num);
        double t=x;
        if(num/t==t)return true;
        return false;
    }
}

昨天的困难题晚上有时间在整理吧

posted @ 2021-11-04 09:55  写不完作业还要玩  阅读(35)  评论(0编辑  收藏  举报