【leetcode 力扣刷题】数学题之数的开根号:二分查找

用二分查找+牛顿迭代解决开根号

  • 69. x的平方根
  • 367. 有效的完全平方数

69. x的平方根

题目链接:69. x的平方根
题目内容:
在这里插入图片描述
题意是要我们求一个数的算数平方根,但是不能使用内置函数,那么我们就暴力枚举。我们知道如果y>=2的话,y*y >= 2*y,所以我们不需要遍历1~x,只需要遍历1~x/2。需要注意x很大时,判断y*y和x的大小关系,y*y可能会溢出,因此应该换成比较y和x/y的大小关系。完整代码如下(C++):

class Solution {
public:int mySqrt(int x) {//特殊情况——0、1,实际上不单独写也行if(x == 1) return 1;long curr = 1;//不能用curr*curr,可能会溢出while(curr <= x/curr)curr++;//循环结束时curr*curr > x,所以需要-1return curr-1;}
};

上面是直接暴力枚举,可以用二分查找来优化,查找范围还是1~x/2。代码如下(C++):

class Solution {
public:int mySqrt(int x) {if(x == 0) return 0;int left = 1, right = x>>1;int ans = 1;//二分法while(left <= right){int mid = left + (right - left)/2;if(mid <= x/mid){ans = mid; //更新ansleft = mid + 1;}else{right = mid - 1;}}return ans;}
};

接下来是一种数学方法——牛顿迭代。假设有函数f(x) = x^2 - C,其中C等于题目给出的x,函数f(x)的零点就是±根号C,其中正的那个向下取整就是答案。牛顿更新法首先将x0初始化为C,在(x0, f(x0))处的切线斜率为2*x0,切线与x轴的交点为x1 = (x0^2 +C/(2*x));之后将x0更新为x1,x0就逐渐向答案逼近。何时终止呢?如果循环用**while(x0 > x/x0)**的话,有些测试用例,比如x=7,会超出时间限制。因为后面x0和x1差异很小,更新非常缓慢,此时也已经接近零点了【因为在零点处,与x轴的交点就是自己】。因此要使用fabs(x1 - x0) < 1e-7这样的条件跳出循环【其中1e-7表示极小的非负数,判断x1和x0是否差异极小,非常接近】。完整代码如下:

class Solution {
public:int mySqrt(int x) {if(x == 0) return 0;double C = x, x0 = x;while(x0 > x/x0){double x1 = 0.5 *(x0 + C/x0);if(fabs(x0 - x1) < 1e-7)break;x0 = x1;}return int(x0);}
};

367. 有效的完全平方数

题目链接:367. 有效的完全平方数
题目内容:
在这里插入图片描述
这道题目和上面一道题目其实是一样的。用上面题的方法求得其向下取整的平方根ans,如果ans*ans == num,就说明其是完全平方数,如果ans*ans < num,说明其不是完全平方数。
代码如下:(C++)

  • 暴力
class Solution {
public:bool isPerfectSquare(int num) {if(num == 1) return true;long curr = 1;while(curr < num/curr)curr++;//判断if(curr*curr == long(num)) return true;return false;}
};
  • 二分
class Solution {
public:bool isPerfectSquare(int num) {if(num == 0) return true;int left = 1, right = num/2;long ans = 1;while(left <= right){int mid = left + (right - left)/2;if(mid <= num/mid){ans = mid;left = mid + 1;}else right = mid - 1;}return ans*ans == long(num) ? true : false;}
};
  • 牛顿迭代
class Solution {
public:bool isPerfectSquare(int num) {double x0 = num;while( x0 > x0/num){double x1 = 0.5 *(x0 + num/x0);//跳出循环if(fabs(x0-x1)<1e-7)break;x0 = x1;}return int(x0)*int(x0) == num ? true : false;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/94609.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML5+CSS3+JS小实例:科技感满满的鼠标移动推开粒子特效

实例:科技感满满的鼠标移动推开粒子特效 技术栈:HTML+CSS+JS 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport&qu…

spring boot + Consul 示例 (Kotlin版)

文章目录 1.docker 安装consul2.创建基于springboot的client2.1 依赖版本2.2 pom.xml2.3 启动类2.4 application.properties 3 搭建完成4. 总结 1.docker 安装consul docker-compose.yaml version: "3"services:consul:image: consul:1.4.4container_name: consule…

卡特兰数

title: 卡特兰数 date: 2021-02-28 16:27:10 tags: 算法 概念 卡特兰数 的通项公式为 又根据 组合数的计算公式: 可得: 同时满足递推关系式: 应用 1.括号化问题&#xff08;或者01的个数问题&#xff09; “ 矩阵链乘&#xff1a; Pa1a2a3……an&#xff0c;依据乘法结合律&…

每日一题 1372二叉树中的最长交错路径

题目 给你一棵以 root 为根的二叉树&#xff0c;二叉树中的交错路径定义如下&#xff1a; 选择二叉树中 任意 节点和一个方向&#xff08;左或者右&#xff09;。如果前进方向为右&#xff0c;那么移动到当前节点的的右子节点&#xff0c;否则移动到它的左子节点。改变前进方…

内存四区(个人学习笔记黑马学习)

1、内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域&#xff1a; 代码区:存放函数体的二进制代码&#xff0c;由操作系统进行管理的全局区:存放全局变量和静态变量以及常量栈区:编译器自动分配释放,存放函数的参数值,局部变量等 堆区:由程序员分配和释放,若程…

了解JVM(JavaEE初阶系列19)

目录 前言&#xff1a; 1.JVM是如何运行的 2.JVM中的内存区域划分 3.JVM的类加载机制 3.1JVM加载机制的五大步骤 3.1.1加载 3.1.1验证 3.1.1准备 3.1.1解析 3.1.1初始化 3.2总结 3.3JVM启动时机 3.4双亲委派模型 4.JVM中的垃圾回收策略 4.1JVM垃圾回收机制概念 …

如何在Windows / Mac / iPhone / Android / Online上将MP4转换为MP3

如果只想保留MP4视频的音频轨道&#xff0c;则可以将MP4转换为MP3格式。 MP3是几乎所有设备&#xff0c;播放器和编辑器都支持的数字音频格式。无论您将MP4视频转换为MP3音频以进行脱机播放或进一步编辑&#xff0c;都可以提取音轨并保存为MP3格式。这是在不损失质量的情况下将…

封装(个人学习笔记黑马学习)

1、格式 #include <iostream> using namespace std;const double PI 3.14;//设计一个圆类&#xff0c;求圆的周长 class Circle {//访问权限//公共权限 public://属性//半径int m_r;//行为//获取圆的周长double calculateZC() {return 2 * PI * m_r;} };int main() {//通…

VC++使用Microsoft Speech SDK进行文字TTS朗读

Microsoft Speech SDK下载地址 https://www.microsoft.com/en-us/download/details.aspx?id10121 需要msttss22L.exe、SpeechSDK51.exe、SpeechSDK51LangPack.exe三个&#xff0c;下载后全部安装 使用VS2005建立一个win32控制台项目 朗读"hello word"、中文“你好”…

Mac安装brew、mysql、redis

mac安装brew mac安装brewmac安装mysql并配置开机启动mac安装redis并配置开机启动 mac安装brew 第一步&#xff1a;执行. /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"第二步&#xff1a;输入开机密码 第三…

python 深度学习 解决遇到的报错问题4

目录 一、DLL load failed while importing _imaging: 找不到指定的模块 二、Cartopy安装失败 三、simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 四、raise IndexError("single positional indexer is out-of-bounds") 五、T…

Java Stream与多线程

Java Stream 1. 问题引入 学习了尚硅谷的JUC&#xff0c;周阳老师讲的商城比较价格的案例&#xff0c;自己模拟了一个多线程的demo, 多线程处理任务并且汇总结果&#xff0c;出现了疑问&#xff0c;实例代码放在下面&#xff0c;读者有兴趣的话可ctrlcv玩一玩 如下是自定义的任…