一【题目类别】
- 二分查找
二【题目难度】
- 简单
三【题目编号】
- 367.有效的完全平方数
四【题目描述】
- 给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false。
五【题目示例】
- 示例 1:
输入:num = 16
输出:true - 示例 2:
输入:num = 14
输出:false
六【题目提示】
- 1 < = n u m < = 2 31 − 1 1 <= num <= 2^{31} - 1 1<=num<=231−1
七【题目进阶】
- 进阶:不要 使用任何内置的库函数,如 sqrt 。
八【解题思路】
- 这道题很巧妙的利用了二分查找,从1到目标值作为区间,左指针指向1,右指针指向目标值,如果min*mid == 目标值,那么肯定是完全平方数,如果mid * mid < num,那么当前数如果有完全平方数肯定在mid的右边,所以mid+1,反之mid-1。注:有个小细节,要用long类型接受值,因为测试用例有的值很大,超出了int类型的取值范围
九【时间频度】
- 时间复杂度:线性时间复杂度 O ( l o g N ) O(logN) O(logN)
十【代码实现】
- Java语言版
package BinarySearch;
public class p367_ValidPerfectSquare {
public static void main(String[] args) {
int num = 256;
boolean res = isPerfectSquare(num);
System.out.println(num + "是完全平方数");
}
public static boolean isPerfectSquare(int num) {
// 这种情况也就是num=1,特例直接返回
if (num < 2) {
return true;
}
// 下面就是常规的二分查找方法,只要从中间开始,如果中间值的平方=num,直接返回true,如果中间值的平方<num,left位置变换,如果中间值的平方>num,right位置变换,,要注意一点用long类型,因为后面的用例超出了int的范围,会导致超出时间限制
long left = 0;
long right = num;
long mid;
while (left <= right) {
mid = (left + right) / 2;
long square = mid * mid;
if (square == num) {
return true;
} else if (square < num) {
left = mid + 1;
} else if (square > num) {
right = mid - 1;
}
}
return false;
}
}
- C语言版
#include<stdio.h>
#include<stdbool.h>
bool isPerfectSquare(int num)
{
if (num < 2)
{
return true;
}
long left = 0;
long right = num;
long mid;
while (left <= right)
{
mid = (left + right) / 2;
long square = mid * mid;
if (square == num)
{
return true;
}
else if (square < num)
{
left = mid + 1;
}
else if (square > num)
{
right = mid - 1;
}
}
return false;
}
int main(void)
{
/*主函数省略*/
}
十一【提交结果】
-
Java语言版
-
C语言版