启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情
该题是数组二分查找题型第五题。
题目来源
题目描述(简单)
给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
进阶:不要 使用任何内置的库函数,如 sqrt 。
示例1
输入: num = 16
输出: true
示例2
输入: num = 14
输出: false
提示
题目解析
基础方法直接使用内置函数即可,但进阶要求中要求 不能使用任何内置的库函数 ,所以 LeetCode —— 69. x 的平方根 - 掘金 中的袖珍计算器算法也只能算基础方法的一种。
二分查找
当我们以二分查找的思维去看待这题时,你会发现该题默认满足有序且无重复的条件,即一个长度为 num ,从 1 开始到 num 结束且递增无重复的数组。在之前的几题中我习惯使用 Math.floor() 该方法避免右区间或中位值 mid 赋值为浮点数,其实可以采用 parseInt() 函数替代。
代码(进阶)
/**
* @param {number} num
* @return {boolean}
*/
var isPerfectSquare = function(num) {
let left = 1, right = parseInt(num / 2) + 1
while (right >= left) {
let mid = parseInt((left + right) / 2)
if(mid * mid > num){
right = mid - 1
}else if (mid * mid < num) {
left = mid + 1
}else {
return true
}
}
return false
};
如图:
内置函数
该方法十分简单主要根据完全平方根的特性,判断 num 的平方根是否为整数即可。
代码
/**
* @param {number} num
* @return {boolean}
*/
var isPerfectSquare = function(num) {
return Math.sqrt(num) === parseInt(Math.sqrt(num))
};
如图:
暴力
如果 num 是完全平方数,那么一定存在正整数 square 满足 square * square = num 。于是我们朴素的遍历寻找是否存在 sqaure 满足该条件。当然在遍历中出现 square * square > num 的情况时,那么代表 square 不存在,直接返回 false 即可。
代码
/**
* @param {number} num
* @return {boolean}
*/
var isPerfectSquare = function(num) {
let square = 1
while (square * square <= num) {
if (square * square === num){
return true
}
square++
}
return false
};
如图:
等差数列求和
经过 LeetCode —— 69. x 的平方根 - 掘金 和该题,做梦时,我居然回忆到高中讲等差数列时,将 ( ),第 i 项为 的等差数列求和后,必定为完全平方数。
因此该方法是将 num 减去等差数列的 第 i 项( ( ), i 从 1 开始)。如果 num 出现 0 ,则 num 是完全平方数,反之为不完全平方数。
代码
/**
* @param {number} num
* @return {boolean}
*/
var isPerfectSquare = function(num) {
for (let i = 1;i <= num;i+=2){
num -= i
if (num === 0){
return true
}
}
return false
};
执行用时和内存消耗仅供参考,大家可以多提交几次。如有更好的想法,欢迎大家提出。