LeetCode - 367. Valid Perfect Square

一开始的想法是从1到n / 2 + 1逐个遍历,看i * i == n?但是这样写应该是无法通过LeetCode测试的,因为一般只要涉及到i * i的问题,LeetCode都会给出一个非常大的数字,让i * i几乎一定达到overflow的地步,所以这里的写法应该是Math.abs(n * 1.0 / i - i) < 0.00000001,用这种方法来判断i * i == n?。时间复杂度为O(n),可惜在LeetCode上面TLE了,但是代码还是贴在这里,有不少可取之处:

public class Solution {
    public boolean isPerfectSquare(int num) {
        if(num < 0) return false;
        
        for(int i = 1; i <= num / 2 + 1; i++){
            if(Math.abs(num * 1.0 / i - i) < 0.00000001) return true;
        }
        return false;
    }
}


时间复杂度比O(n)还低,自然是使用O(logn)的binary search,对1到n / 2 + 1这个范围进行搜索,注意mid的计算要使用mid = left + (right - left) / 2,否则可能会造成overflow(都是套路....),接下来相等条件的判断也要使用Math.abs(n * 1.0 / i - i) < 0.00000001,防止overflow。注意这里while中的条件是left <= right,为了包括n = 1的情况,代码如下:

public class Solution {
    public boolean isPerfectSquare(int num) {
        if(num < 0) return false;
        
        int l = 1;
        int r = num / 2 + 1;
        
        while(l <= r){
            int mid = l + (r - l) / 2;
            if(Math.abs(num * 1.0 / mid - mid) < 0.0000001) return true;
            else if(num * 1.0 / mid > mid) l = mid + 1;
            else r = mid - 1;
        }
        return false;
    }
}


知识点:

1. 代码中出现a * a == b?的问题的时候要转化为除法,防止overflow

2. Binary Search中mid = left + (right - left) / 2,防止overflow

3. Binary Search中while的循环条件到底是left < right还是left <= right要进行一些判断,不要随意那一个就来

4. 当题目的输入时integer的时候要特别注意一些特殊的情况,比如负数,0,1,2(与质数相关),检查的时候将其考虑在内

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值