Java練習(xí)題之實現(xiàn)平方根(sqrt)函數(shù)
前言
可使用java.lang.Math類的sqrt(double)方法求平方根。Math是java.lang包中的類,而Double為對象中的基本類型。但是如果不使用庫函數(shù)呢?有什么辦法實現(xiàn)平方根函數(shù)呢?
方法:二分查找、牛頓迭代法、利用平方數(shù)的性質(zhì)
利用平方數(shù)的性質(zhì)
平方數(shù)的性質(zhì):n²=1+1+2+2+....+n-1+n-1+n。例如4²=1+1+2+2+3+3+4=16。
1+3為2的平方,1+3+5為3的平方,

也就是說每一次加一個奇數(shù),再設(shè)置一個變量記錄加了多少個奇數(shù)。
復(fù)雜度分析:
時間復(fù)雜度:O(N),每次+2的循環(huán),為(1/2)N的時間復(fù)雜度,去掉系數(shù),為O(N)
空間復(fù)雜度: O(1),只使用了有限常數(shù)個變量;
int sqrt(int x) {
if(x<=0) return 0; //小于等于0 返回0
int ans = 1;
int num = 1;
int i = 3;
while(num+i<=x){
num+=i;
ans ++; // 每加一個奇數(shù),ans+1
i += 2;
}
return ans;
}二分查找
如果求解一個數(shù)的平方根,這個結(jié)果肯定是在1到這個數(shù)的范圍,因此我們可以使用二分查找的方法。例如求解x的平方根,思路:
- 初始范圍:1 ~ x,使用left標(biāo)記1,right標(biāo)記x ,取left~right的中間值,為 middle;
- 當(dāng)middle*middle <= x && (middle+1)*(middle+1) > x時,返回結(jié)果
- 當(dāng) middle*middle < x時,到右半部分繼續(xù)尋找,范圍改成 middle+1 ~ right
- 當(dāng)middle*middle > x時,到左半部分繼續(xù)尋找,范圍改成 left ~ middle+1
注: 這種方法只能使用于整數(shù)的開跟

復(fù)雜度分析:
時間復(fù)雜度:O(logn),二分查找的復(fù)雜度,每次循環(huán)減少一半
空間復(fù)雜度;O(1),只使用了有限常數(shù)個變量;
代碼實現(xiàn):
public int mySqrt(int x) {
if (x <= 0) {
return 0;
}
int left = 1, right = x;
while (true) {
int middle = (left + right) >> 1;
if (middle <= x / middle && (middle+1) > x / (middle+1)) {
return (int) middle;
} else if (middle < x / middle) {
left = middle + 1;
} else {
right = middle - 1;
}
}
}牛頓迭代法
牛頓迭代法簡介
假設(shè)方程 F(x)=0 在 x 附近有一個根,那么用以下迭代式子:
依次計算X1、X2、X3、...........那么序列將無限逼近方程的根。
牛頓迭代法的原理很簡單,其實是根據(jù)f(x)在x0附近的值和斜率,估計f(x)和x軸的交點,看下面的動態(tài)圖:

代碼示例:
public class Solution {
public int sqrt (int x) {//牛頓迭代法
if(x==0||x==1) return x;//題中告訴我們x的范圍: 0 <= x < 2^31-1
long X0 = x;//使用int進(jìn)行加法運算可能溢出,所以采用long型
long X1 = 0;//下一個迭代變量,為了方便理解,也可只使用X0
while(X0 > x/X0 ) { // X0^2>x循環(huán)
X1=(X0+x/X0) >> 1;//由迭代公式得,采用右移1位操作代替除以2,運算更快
X0=X1;//把下一個迭代變量賦給X0,統(tǒng)一操作,方便繼續(xù)處理
}
return (int)X0;//返回值類型為int,因此需要做強制類型轉(zhuǎn)換
}
}總結(jié)
牛頓迭代法不像二分查找法、平方數(shù),需要喚醒一下各位哥哥姐姐們的高中數(shù)學(xué)知識,只有這樣才能理解該公式。如果喚醒失敗,推薦使用二分查找法,不要逞強哦。
到此這篇關(guān)于Java練習(xí)題之實現(xiàn)平方根(sqrt)函數(shù)的文章就介紹到這了,更多相關(guān)Java平方根sqrt函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot日期格式轉(zhuǎn)換之配置全局日期格式轉(zhuǎn)換器的實例詳解
這篇文章主要介紹了SpringBoot日期格式轉(zhuǎn)換之配置全局日期格式轉(zhuǎn)換器的實例詳解,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
springboot項目打包的可執(zhí)行jar運行報錯問題及解決
本文介紹了SpringBoot項目打包成可執(zhí)行jar文件后無法使用java-jar命令啟動的問題及解決方法,主要是需要在pom.xml文件中添加spring-boot-maven-plugin插件,以便生成正確的MANIFEST.MF文件2026-04-04
搭建MyBatis開發(fā)環(huán)境及基本的CURD介紹
這篇文章主要介紹了搭建MyBatis開發(fā)環(huán)境及基本的CURD,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
Java二維碼登錄流程實現(xiàn)代碼(包含短地址生成,含部分代碼)
近年來,二維碼的使用越來越風(fēng)生水起,本篇文章主要介紹了Java二維碼登錄流程實現(xiàn)代碼,其中包含短地址生成,有興趣的可以了解一下。2016-12-12
SpringBoot項目配置多數(shù)據(jù)源的兩種方式詳解
這篇文章主要為大家詳細(xì)介紹了SpringBoot項目配置多數(shù)據(jù)源的兩種方式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2026-01-01
解析SpringBoot整合SpringDataRedis的過程
這篇文章主要介紹了SpringBoot整合SpringDataRedis的過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06



