leetcode日記 69 x的平方根

2021-10-05 21:59:57 字數 1561 閱讀 9535

今天的每日一題比較……奇特。

實現 int sqrt(int x) 函式。

計算並返回 x 的平方根,其中 x 是非負整數。

由於返回型別是整數,結果只保留整數的部分,小數部分將被捨去。

示例 1:

輸入: 4 輸出: 2 示例 2:

輸入: 8 輸出: 2 說明: 8 的平方根是 2.82842…,

由於返回型別是整數,小數部分將被捨去。

我直接貼我在力扣寫的第一次題解:

emmmmmmm,算上讀題目我只寫了1min不到……大汗淋漓

int

mysqrt

(int x)

int

invsqrt

(float x)

intmysqrt

(int x)

執行結果:

雖然可能有人看不太懂這段**,但是沒關係,能過就行。而且執行效率依然雙百。

不過效率不如庫函式,偶爾會花4ms。提交三次左右就能看見雙百的結果。

效率算是最棒的了。思想是快速地蒙出乙個平方根的倒數,然後用牛頓迭代法快速逼近取值。效率很高。

分析程式之前,我們必須解釋一下float資料在計算機裡的表示方式。一般而言,乙個float資料 x 共32個bit,和int資料一樣。其中前23位為有效數字 m_x ,後面接著乙個8位資料 e_x 表示指數,最後一位表示符號,由於這裡被開方的數總是大於0,所以我們暫不考慮最後乙個符號位。此時

x=1.m_x 2^

如果我們把計算機內的浮點數 x 看做乙個整數 i_x ,那麼

i_x = 2^e_x+m_x

現在開始逐步分析函式。這個函式的主體有四個語句,分別的功能是:

int i = (int)&x; 這條語句把 x 轉成 i=i_x 。

i = 0x5f3759df - (i>>1); 這條語句從 i_x 計算 i_} 。

y = (float)&i; 這條語句將 i_} 轉換為 1/\sqrt 。

y = y*(1.5f - xhalfyy); 這時候的y是近似解;此步就是經典的牛頓迭代法。迭代次數越多越準確。

關鍵是第二步 i = 0x5f3759df - (i>>1); 這條語句從 i_x 計算 i_} ,原理:

令 y=1/\sqrt ,用 x=(1+m_x)2^ 和 y=(1+m_y)2^ 帶入之後兩邊取對數,再利用近似表示 \log_2(1+z)\sim z+\delta ,算一算就得到

i_y = \frac(127-\delta)2^-i_x/2

若取 \delta=0.0450465679168701171875 , \frac(127-\delta)2^ 就是程式裡所用的常量0x5f3759df。至於為何選擇這個 \delta ,則應該是曲線擬合實驗的結果。

部分內容**:

LeetCode 簡單 69 x 的平方根

實現 int sqrt int x 函式。計算並返回 x 的平方根,其中 x 是非負整數。由於返回型別是整數,結果只保留整數的部分,小數部分將被捨去。示例 1 輸入 4 輸出 2 示例 2 輸入 8 輸出 2 說明 8 的平方根是 2.82842 由於返回型別是整數,小數部分將被捨去。class s...

69 x的平方根

一 題目 實現int sqrt int x 函式。計算並返回 x 的平方根,其中 x 是非負整數。由於返回型別是整數,結果只保留整數的部分,小數部分將被捨去。示例 1 輸入 4輸出 2示例 2 輸入 8輸出 2說明 8 的平方根是 2.82842.由於返回型別是整數,小數部分將被捨去。二 思路 採用...

69 x的平方根

題目描述 實現int sqrt int x 函式。計算並返回x的平方根,其中x 是非負整數。由於返回型別是整數,結果只保留整數的部分,小數部分將被捨去。示例 1 輸入 4 輸出 2 示例 2 輸入 8 輸出 2 說明 8 的平方根是 2.82842 由於返回型別是整數,小數部分將被捨去。知識點 二分...