一起刷力扣之【367. 有效的完全平方数】

138 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

题目描述

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false

进阶不要 使用任何内置的库函数,如 sqrt

示例

输入: num = 16
输出: true
输入: num = 14
输出: false

提示

  • 1 <= num <= 2^31 - 1

暴力法

由于不能使用内置的库函数,那么我们只好使用一个笨方法,将一个个数值进行相乘来比较,判断目标值是否为完全平方数。参考提示中给出的目标值范围,我们需要在一个个数值相乘的基础上做好边界的处理,不然会导致该方法超时。

class Solution {
    public boolean isPerfectSquare(int num) {
        // 边界判断
        if(num == 1){
            return true;
        }
        
        long sqrt = 2L;
        
        // 如果该数值相乘的和超过目标值则不再比较后续的数值
        while(sqrt * sqrt <= num){
            // 目标值判断
            if(sqrt * sqrt == num){
                return true;
            }
            // 不符合,数值自增 1
            ++sqrt;
        }

        return false;
    }
}

二分法

暴力法需要一个个数值进行比较,如果目标值太大的话,需要话费的时间太多了。那么我们能不能使用二分法来进行优化呢?

  1. 获取数值边界【1,num】
  2. 取中间值,判断其相乘结果大于或小于目标值,然后移动边界,排除掉一半的元素
  3. 重复步骤2,直至找到目标值或者停止循环
  4. 返回结果
class Solution {
    public boolean isPerfectSquare(int num) {
        // 确定左右两个边界
        int left = 0, right = num;
        
        // 终止条件
        while (left <= right) {
            // 取得中间值
            int mid = left + (right - left) / 2;
            // 计算相乘的结果
            long sqrt = (long) mid * mid;
            // 等于目标值,返回
            if(sqrt == num){
                return true;
            }else if(sqrt > num){
                // 大于目标值,右边边界左移
                right = mid - 1;
            }else{
                // 小于目标值,左边边界右移
                left = mid + 1;
            }
        }
        
        // 不符合,返回结果
        return false;
    }
}