壹 ❀ 引

这几天心情复杂,也不知道形容。做道题吧,其实是上周的题,一直没整理,比较巧的是,这也是我同学17年去PPTV面试时遇到的一题,题目来自leetcode69. x 的平方根,题目描述如下:

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2

示例 2:

输入: 8
输出: 2

说明: 8 的平方根是 2.82842...,

由于返回类型是整数,小数部分将被舍去。

站在JavaScript角度,其实就是让我们自己实现Math.sqrt方法,题目也不用分析了,唯一需要注意的是,比如8这样的数字平方根为2.82842...,因此取2,而非取3,让我们来实现它。

贰 ❀ 解题思路

Math中除了有求平方根的sqrt方法以外,其实还有求幂的pow,因此我们可以利用pow直接解题:

/**
* @param {number} x
* @return {number}
*/
var mySqrt = function (x) {
return Math.floor(Math.pow(x, 0.5));
};

当然,我们也可以使用笨一点的方法,由于0和1的平方根等于自己,所以从2开始,只要当第一个数字的平方比x还大,那么我们返回此数字减一位即可,像这样:

/**
* @param {number} x
* @return {number}
*/
var mySqrt = function (x) {
// 考虑0和1
if(x<2){
return x;
};
// 从2开始查找
let a = 2;
while (a * a <= x) {
a++;
};
return a - 1;
};

很明显,虽然这样做能实现,但是查找起来很慢,如果x的平方根越大,我们需要遇到它耗时就越久。而官方对于此题推荐的做法是使用二分查找。

举个例子,假设输入的是100,我们要找的就是10,由于上面的答案也分析了,0与1可以直接返回,所以left起点可以从2开始,那么右边边界怎么定呢?其实我们可以将右边起点定为Math.floor(x/2),为啥?0,1不用考虑,紧接着是数字2,2也是唯一一个的2次方后再除以2与自己相等的数,再往上走的任意数字,比如3的2次方为9,9除以2为4.5,显而易见4.5的二次方要比3的二次方大,直接将x除以2求floor的数完全没问题。

这里有个小技巧,当我们想让9/2为4时,一般的做法是前面说的结合Math.floor,其实还可以使用位运算符,这个跟二进制有关,大家先知道是这么回事就行。

9>>1 //4
8>>1 //4
6>>1 //3

也就是说,将数字除以2,如果能整除得到的就是这个整数,如果不能,则用floor向下取整,比如9>>1就是因为为4.5经过向下取整得到的结果。

我们先上代码:

/**
* @param {number} x
* @return {number}
*/
var mySqrt = function (x) {
if (x < 2) {
return x
};
let left = 2,
right = x >> 1;//这里等同于Math.floor(x/2)
while (left <= right) {
// 同理,这里也是用了位运算符,保证mid是个整数
let mid = left + ((right - left) >> 1);
//使用x/mid而非mid*mid是怕数字越界
if (mid === x / mid) {
return mid
} else if (mid < x / mid) {
left = mid + 1
} else {
right = mid - 1
};
};
// 最后直接用right和x/right相比较,如果大肯定取left,反之取right
return right > x / right ? left : right
};

唯一需要注意的是,二分法中取mid我在之前的文章中用的是Math.floor((low + high) / 2),但是网友说这样容易越界,也就是假设hight很大了,偏偏加了low已经越界,就无法参与计算了。所以另外一种求中间的做法就是left + Math.floor((right-left)/2),由于使用了位运算,所以就简写成left + ((right - left) >> 1)了,至于后面的判断也就是用x/mid与mid比较的问题,也不用过多解释。

最后我们总是会得到left与right两个数,再做最后一次比较即可。

那么本文就到这里了。

JS leetcode x 的平方根 题解分析的更多相关文章

  1. Leetcode 10. 正则表达式匹配 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  2. node.js基础模块http、网页分析工具cherrio实现爬虫

    node.js基础模块http.网页分析工具cherrio实现爬虫 一.前言      说是爬虫初探,其实并没有用到爬虫相关第三方类库,主要用了node.js基础模块http.网页分析工具cherri ...

  3. diff.js 列表对比算法 源码分析

    diff.js列表对比算法 源码分析 npm上的代码可以查看 (https://www.npmjs.com/package/list-diff2) 源码如下: /** * * @param {Arra ...

  4. C#版 - Leetcode 306. 累加数 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  5. C#版(击败100.00%的提交) - Leetcode 372. 超级次方 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. Leetcod ...

  6. C#版(打败97.89%的提交) - Leetcode 202. 快乐数 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  7. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

  8. 病毒木马查杀实战第025篇:JS下载者脚本木马的分析与防御

    前言 这次我与大家分享的是我所总结的关于JS下载者脚本木马的分析与防御技术.之所以要选择这样的一个题目,是因为在日常的病毒分析工作中,每天都会遇到这类病毒样本,少则几个,多则几十个(当然了,更多的样本 ...

  9. LeetCode-343. 整数拆分 - 题解分析

    题目来源 343. 整数拆分 题目详情 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化. 返回 你可以获得的最大乘积 . 示例 1: 输入: ...

  10. js网页滚动条滚动事件实例分析

    本文实例讲述了js网页滚动条滚动事件用法.分享给大家供大家参考.具体分析如下: 在做js返回顶部的效果时,要监听网页滚动条滚动事件,这个事件就是:window.onscroll.当onscroll事件 ...

随机推荐

  1. Angular系列教程之MVC模式和MVVM模式

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  2. [转帖]MySQL运维实战(2)MySQL用户和权限管理

    https://segmentfault.com/a/1190000044514403 作者:俊达 引言 MySQL数据库系统,拥有强大的控制系统功能,可以为不同用户分配特定的权限,这对于运维来说至关 ...

  3. [转帖]nginx中rewrite和if的用法及配置

    nginx中rewrite和if的用法及配置 文章目录 nginx中rewrite和if的用法及配置 @[toc] 一.rewrite应用 1.rewrite跳转场景 2.rewrite实际场景 3. ...

  4. [转帖]mysql-connect-java驱动从5.x升级到8.x的CST时区问题

    https://juejin.cn/post/7029291622537887774   前言 旧项目MySQL Java升级驱动,本来一切都好好的,但是升级到8.x的驱动后,发现入库的时间比实际时间 ...

  5. [转帖]TLB缓存是个神马鬼,如何查看TLB miss?

    https://zhuanlan.zhihu.com/p/79607142 介绍TLB之前,我们先来回顾一个操作系统里的基本概念,虚拟内存. 虚拟内存 在用户的视角里,每个进程都有自己独立的地址空间, ...

  6. [转帖]查看mysql分区名和各分区数据量

    – 查看mysql分区名和各分区数据量 SELECT table_name, partition_name, table_rows FROM information_schema.PARTITIONS ...

  7. [转帖]OpenSSL版本历史

    OpenSSL版本历史 新闻日志 这是所有 OpenSSL 公告的简洁日志.它们几乎是发布通知. 日期物品 2021 年 7 月 29 日OpenSSL 3.0 的 Beta 2 现已推出.这是一个候 ...

  8. [转帖]Linux—解压缩命令总结(tar/zip)

    https://www.jianshu.com/p/1ad5d852d13b 1 tar 1.2 tar介绍   tar命令是linux系统中对文件和目录解压缩命令.tar命令可以用于对后缀名为.ta ...

  9. [转帖]ldconfig命令

    https://linux265.com/course/linux-command-ldconfig.html ldconfig命令的作用主要是在默认搜寻目录/lib和/usr/lib以及动态库配置文 ...

  10. [转帖]数据库篇-MySql架构介绍

    https://zhuanlan.zhihu.com/p/147161770 公众号-坚持原创,码字不易.加微信 : touzinv 关注分享,手有余香~ 本篇咱们也来聊聊mysql物理和逻辑架构,还 ...