每日一题:有效的完全平方数

511 阅读1分钟

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

leetcode题目链接

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

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

示例 1:

输入:num = 16
输出:true

示例 2:

输入:num = 14
输出:false

提示:

1 <= num <= 2^31 - 1

解题思路:

这道题我们可以选择使用二分查找来做

具体思路:

  1. 因为一个数的项再大不可能是数值本身(1除外),我们就可以将区间范围限定在 1到num 中,进行二分查找

  2. 判断每次取到的中间值(这里先说明下:mid是中间值,num是题目需要我们所判断的数,left 是左指针,从1开始;right 是右指针,从num开始

  • 如果 num / mid == midmid mid == numnum 就是一个完全平方数
  • 如果 num / mid > mid,说明中间值 mid 比我们要找的项小,因此 mid 前面的数都不需要了,包括 mid 本身 ,左指针 left 移动到 mid 的 后一位,即 left = mid + 1;
  • 如果 num / mid < mid,说明中间值 mid 比我们要找的项大,因此 mid 后面的数都不需要了,包括 mid本身,右指针 right 移动到 mid 的 前一位,即 right = mid - 1;

代码实现:(java)

//这里是当num为0和2时,都不是完全平方数,我们可以直接返回false
if (num == 0 || num == 2) {
    return false;
}

if (num == 1) {
    return true;
}

int left = 1;
int right = num;
while (left <= right) {
    int mid = left + (right - left)/2;
    //这里需要判断两次的原因是因为有的数除以项后,明明有余数,系统会忽略到余数,取比较靠左的项,这样明显不严谨
    //所以我们由加了一次判断,判断 项相乘 是否等于num
    //就拿5来说,5/2 = 22 == mid ,就会返回 true,但结果明显不对,所以我们就要再判断下2*2是否等于5
    if (num / mid == mid) {
        if (mid * mid == num) {
            return true;
        }else {
            return false;
        }
    }else if (num / mid < mid) {
        right = mid - 1;
    }else if (num / mid > mid) {
        left = mid + 1;
    }
}
return false;

复杂度分析:

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1) 输出

image.png