LeetCode二分查找:有效的完全平方数

  • 如果评论区没有及时回复,欢迎来公众号:ByteCode 咨询
  • 公众号:ByteCode。致力于分享最新技术原创文章,涉及 Kotlin、Jetpack、算法、译文、系统源码相关的文章

题目来源于 LeetCode 上第 367 号(Valid Perfect Square)问题:有效的完全平方数。题目难度为 Easy。

题目描述

Given a positive integer num, write a function which returns True if num is a perfect square else False.

Note:

Do not use any built-in library function such as sqrt.

Example 1:

Input: 16
Output: true

Example 2:

Input: 14
Output: false

思路:二分查找

什么是完全平方数?维基百科

数学上,平方数,或称完全平方数,是指可以写成某个整数的平方的数,即其平方根为整数的数。例如,9 = 3 × 3,它是一个平方数。

二分法的解题思路大致以下几个步骤:

  • 寻找完全平方数 x 的区间范围:[low, height]
  • 用二分法在区间 [low, height] 内寻找完全平方数
    • 当 low <= height 时:
      令 mind = (low + height) / 2,square = mind * mind 比较 square 与 x:
      • 如果 square > x,则 height = mind -1。
      • 如果 square < x,则 low = mind + 1。
      • 如果 square == x,即完全平方数为 mind,返回 true。
    • 如果在区间内没有找到,则返回 false。

如何确定 x 的区间范围:[low, height]?

根据上面的概念 完全平方数 是某个整数的平方的数,也就是说 完全平方数 = n *n,例如,9 = 3 × 3

  • 当 x >= 2 时:它的整数平方根一定小于 x / 2 且大于 0,即 0 < a < x / 2
  • 当 x =1 时:即 1 / 2 的值为0了,所以为了兼顾 1 的特殊情况,需要将边界设为 x / 2 +1

综合以上两种情况 x 的区间范围:[0, x / 2 + 1],为了提高效率所以使用了位运算符,即 x/2 等价于 x >>> 1

Java实现

public class Solution {
public boolean isPerfectSquare(int num) {
long low = 0;
long height = (num >>> 1) + 1;
while (low <= height) {
long mind = (low + height) >>> 1;
long square = mind * mind;
if (square == num) {
return true;
} else if (square < num) {
low = mind + 1;
} else {
height = mind - 1;
}
}
return false;
}
}

Koltin实现

class Solution {
fun isPerfectSquare(num: Int): Boolean {
var low = 0L
var height = (num ushr 1).toLong() + 1
var target = num.toLong()
while (low <= height) {
val mind: Long = (low + height) ushr 1
val square = mind * mind
when {
square == target -> return true
square < target -> low = mind + 1
else -> height = mind - 1
}
}
return false
}
}

致力于分享一系列 Android 系统源码、逆向分析、算法、翻译、Jetpack 源码相关的文章,在技术的道路上一起前进

Android10 源码分析

正在写一系列的 Android 10 源码分析的文章,了解系统源码,不仅有助于分析问题,在面试过程中,对我们也是非常有帮助的,如果你同我一样喜欢研究 Android 源码,可以关注我 GitHub 上的 Android10-Source-Analysis

算法题库的归纳和总结

由于 LeetCode 的题库庞大,每个分类都能筛选出数百道题,由于每个人的精力有限,不可能刷完所有题目,因此我按照经典类型题目去分类、和题目的难易程度去排序。

  • 数据结构: 数组、栈、队列、字符串、链表、树……
  • 算法: 查找算法、搜索算法、位运算、排序、数学、……

每道题目都会用 Java 和 kotlin 去实现,并且每道题目都有解题思路,如果你同我一样喜欢算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:Leetcode-Solutions-with-Java-And-Kotlin

精选国外的技术文章

目前正在整理和翻译一系列精选国外的技术文章,不仅仅是翻译,很多优秀的英文技术文章提供了很好思路和方法,每篇文章都会有译者思考部分,对原文的更加深入的解读,可以关注我 GitHub 上的 Technical-Article-Translation

评论