【每日一題】LeetCode. 69. x的平方根

每日一題,防止癡呆 = =

一、題目大意

實現 int sqrt(int x) 函數。
計算並返回 x 的平方根,其中 x 是非負整數。
由於返回類型是整數,結果只保留整數的部分,小數部分將被捨去。
在這裏插入圖片描述

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/sqrtx

二、題目思路以及AC代碼

這題確實思路很多,但是確實沒有想到可以用數值計算的方法求解 = =。

思路一

首先比較有意思的是,可以直接用STL的sqrt方法通過,雖然這樣通過的也沒什麼用,畢竟不是考你調庫。

思路二

可以直接暴力,即遍歷1~x的所有整數,遍歷元素爲i,如果ii等於x,那麼結果就是i,如果沒有遇到相等的,但第一次遇到ii > x,那麼 i-1 就是結果。

思路三

既然可以暴力遍歷,由於這題又有順序,就也可以二分,思路同上,需要注意的是,可能mid*mid並不等於x,小於x,但是由於是取整,所以最後的結果也可能就是這個數,此時在最後的時候,要判斷一下是取l還是l-1。

思路四

前面三個都是比較基礎的思路,哦,第一個不算思路,下面就是看題解看到的比較有意思的了,首先一個是利用其餘的運算來代替根號運算。
在這裏插入圖片描述
如上,就可以將根號運算,轉換爲指數和對數運算了,但由於精度問題,最後要判斷一下,結果是res還是res+1。

思路五

就是數值計算的方法了,利用迭代的方法,求取函數零點。這裏使用的是牛頓法,具體這裏就不介紹了,主要是根據梯度去不斷靠近零點,但要注意初始值的選取,因爲選取不好的話,可能會收斂到另一個零點。

下面給出思路三和思路五的AC代碼,其實一開始暴力也寫了,不過丟了 = =。

思路三,二分

typedef long long ll;

class Solution {
public:
    int mySqrt(int x) {
        int res = 0;

        int l = 0, r = x;
        while (l < r) {
            ll mid = (l + r) >> 1;
            if (mid*mid == x) {
                return mid;
            }

            if (mid*mid < x) l = mid + 1;
            if (mid*mid > x) r = mid - 1;
        }

        if (l*l > x) res = l-1;
        else res = l;

        return res;
    }
};

思路五,牛頓法

class Solution {
public:
    int mySqrt(int x) {
        if (!x) return 0;

        double res = x;
        double last = res;

        double epsilon = 1e-7;

        while (1) {
            res = (res + x/res) / 2;
            if (abs(res - last) <= epsilon) {
                break;
            }
            last = res;
        }

        return res;
    }
};

如果有問題,歡迎大家指正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章