LeetCode 之 JavaScript 解答第69題 —— X 的平方根(Squrt(x))

不甘平凡的小鹿發表於2019-04-18

Time:2019/4/17
Title: sqrt(x)
Difficulty: Easy
Author: 小鹿


題目:sqrt(x)

Implement int sqrt(int x).

Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

實現 int sqrt(int x) 函式。

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

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

Example 1:

Input: 4
Output: 2
複製程式碼

Example 2:

Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since 
             the decimal part is truncated, 2 is returned.
複製程式碼

Solve:

▉ 問題分析

1)根據題目要求,求一個指定樹的平方根,第一要想到的是開平方根是沒有規律可循的,可能想到一個暴力破解法,從 1 開始遍歷,直到滿足 k^2 < x(k+1)^2 > x 為止。

  1. 你可能想到這種方法效率太低,需要從 1 開始,如果 x 很大,豈不是需要遍歷很多?能不能規定一個範圍,在這個範圍中查詢開平方根呢?你會想到,所有數的開平方根得到的值是永遠小於等於自身的(0 是自身),所以 x 的開平方根的值的範圍一定在 0 < k < x 之間。

3)要想在這個區間快速定位找到一個滿足條件的 x ,最高效的方法莫過於二分查詢,但是可能存在小數,這又涉及到二分查詢的四個變體(二分查詢的變形)過程。如果你之前沒有連線過,沒關係,請看我之前記載的一篇文章。

4)雖然我們已經確定瞭解題方法,但是這時候不要著急,想一想這個問題是否滿足二分查詢的四個適用條件?哪四個條件呢?你需要系統學習一下就 ok !

▉ 演算法思路

1)此過程分為兩種情況,負數和正整數,所以要對輸入的 x 進行判斷。

2)然後開始根據二分查詢應該注意的「三個重點」寫出無 bug 的程式碼。

3)對二分查詢進行稍微的變體,因為我們可能查詢的數並不是一個正整數,我們取整數部分就可以了,小數部分省略。

▉ 測試用例

1)輸入 0

2)輸入1

3)輸入負數的 x

4)輸入平方根為正整數的 x

5)輸入平方根為小數的 x

▉ 程式碼實現

寫二分查詢程式碼需要注意的三點:

1)迴圈退出條件。

2)mid 的取值。

3)low 和 hight 的更新。

var mySqrt = function(x) {
     let low = 1;
     let high = x;
     // 如果 x 小於 0 輸出 -1
     if(x < 0) return -1;
     // 迴圈終止條件
     while(low <= high){
        // mid 取值
        let mid = Math.floor(low + ((high - low)/2));
        // 判斷平方是否小於等於
        if(Math.pow(mid,2) <= x){
            // 如果小於等於,如果下一值大於 x 則當前值為 x 平方根的最小整數值
            if(Math.pow(mid+1,2) > x || mid === high){
                return mid;
            }else{
                low = mid + 1;
            }
        }else{
            high = mid - 1;
        }
    }
    return 0;
};
複製程式碼
▉ 效能分析

暴力破解:

  • 時間複雜度:O(n)。你需要從 1 遍歷所有可能的資料,所以時間複雜度為O(n)。
  • 空間複雜度:O(1)。不需要額外的記憶體空間。

二分法:

  • 時間複雜度:O(n)。每次都折半查詢,所以查詢一個元素時間複雜度為O(logn)。
  • 空間複雜度:O(1)。不需要額外的記憶體空間。
▉ 小結

通過這個題我們可以總結一下:

1)如果問題涉及到查詢,我們要想到使用二分查詢來提高效率。

2)使用二分查詢之前,判斷問題是否滿足二分查詢的要求。


歡迎一起加入到 LeetCode 開源 Github 倉庫,可以向 me 提交您其他語言的程式碼。在倉庫上堅持和小夥伴們一起打卡,共同完善我們的開源小倉庫! Github:https://github.com/luxiangqiang/JS-LeetCode
歡迎關注我個人公眾號:「一個不甘平凡的碼農」,記錄了自己一路自學程式設計的故事。

相關文章