Leetcode 367: Valid Perfect Square

问题描述:
Given a positive integer num, write a function which returns True if num is a perfect square else False.
Follow up: Do not use any built-in library function such as sqrt.
判断一个正整数是否是完全平方数,不允许用sqrt

思路:如果从1到num逐一排查,绝对会超时。往往这种情况会考虑用二叉搜索。
问题反思:我想到了用二叉搜索,但是忽略了越界问题,即mid*mid 会超出integer的最大范围。所以我们把left,right, mid全部设为long

代码如下:

class Solution {
    public boolean isPerfectSquare(int num) {
        if(num==1) return true;
        long left=1;
        long right=num;
        while(left<right){
            long mid=left+(right-left)/2;
            //经测试(long)可以不写,java可以比较long和int
            //long 和 int 比较时 int 自动转换成 long
            if(mid*mid==(long)num){  
                return true;
            }
            //同理,(long)可以不写
            else if(mid*mid>(long)num){
                right=mid;
            }
            else{
                left=mid+1;
            }
        }
        return false;
    }
}

时间复杂度: O(logn)

总结:
到目前为止已经做了好多道二叉搜索的题目了,下面总结一下一些容易错的点:

  1. left是从0开始,还是从1开始,还是从什么数开始,要根据题意灵活变化,同理right
  2. 求mid的方法用left+(right-left)/2可以保证不越界, 相反(left+right)/2 可能会在运算left+right时越界
  3. 因为我们求出的mid是“左偏中值”,比如1,2,3,4,我们的中间位置是2而不是3 。 所以如果我们需要取左半部分,right取mid(不减一);如果我们取右半部分,left取mid+1
  4. while循环的条件left<right, 是否含等号要根据具体题意, 但是我习惯不把等号写在循环条件中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值