題目描述:給定一個非負整數 x,請計算並回傳 x 的整數平方根(即 floor(√x)),結果無條件捨去小數部分。不能使用內建的 sqrt() 函式或任何指數運算。
解題思路:對答案範圍 [0, x] 進行二分搜尋。每次取中間值 mid,計算 mid * mid 並與 x 比較:若 mid * mid <= x,則 mid 是合法候選答案,記錄為 ans 並往右搜尋更大值;若 mid * mid > x,則 mid 太大,往左搜尋。迴圈結束後 ans 即為最大的滿足條件的整數,也就是 floor(√x)。重要細節:mid * mid 可能超出 int 的範圍(x 最大為 2^31-1,mid 最大約 46341,mid*mid 約 2.1×10^9 剛好在邊界),因此乘法時必須轉型為 long long 避免溢位。
時間複雜度:O(log x) — 二分搜尋每次將搜尋範圍縮小一半,最多需要 log₂(x) 次迭代,約 31 次(x 最大為 2^31-1)。
空間複雜度:O(1) — 只使用常數個變數(lo、hi、mid、ans),不需額外空間。
1. If x == 0, return 0
2. Set lo = 1, hi = x, ans = 0
3. While lo <= hi:
a. Compute mid = lo + (hi - lo) / 2 (use long long)
b. If mid * mid <= x:
- ans = mid
- lo = mid + 1 (search for larger valid value)
c. Else:
- hi = mid - 1 (mid is too large)
4. Return ans方法一:牛頓迭代法(Newton's Method)
利用數學迭代公式 x_{n+1} = (x_n + S / x_n) / 2 快速逼近 √S。從初始猜測值 x0 = S 開始,每次迭代都能使誤差平方級縮小(二次收斂),收斂速度遠快於二分搜尋。實作時只需迭代至 x_n * x_n <= S 為止。時間複雜度實際上約為 O(log log x),但在整數精度下差異不明顯。
方法二:位元操作逐位確定(Bit Manipulation)
從最高有效位(第 15 位,因為 √(2^31) ≈ 46341 < 2^16)開始逐位嘗試設定結果的每一個二進位位元。若設定後 ans * ans <= x 則保留該位元,否則清除。此法同樣為 O(log x),但常數因子更小,且不依賴除法運算,在某些硬體上更快。
hi - lo < 1e-7;此時時間複雜度如何用 O 記號表示(以初始搜尋範圍 R 和精度 ε 表示)?