↓快轉到主要內容
  1. LeetCode/

LeetCode 3932: Count K-th Roots in a Range

·2 分鐘· ·
LeetCode Medium Binary-Search Math
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2026-05-17

  • 提交紀錄:WA ×4 → AC(05-17)→ WA → TLE → AC → AC(05-18 重寫)

解題思路
#

[l, r] 裡的完全 k 次方數,就是「有幾個整數 x 滿足 l <= x^k <= r」。

設 f(n) = 最大的 x 使得 x^k <= n。那麼:

答案 = f(r) - f(l - 1)

要注意 0 = 0^k 也是完全 k 次方數,所以 x 要從 0 開始算,而且 f(-1) = -1。

我的嘗試
#

第一版:用浮點數比較相等
#

if i ** (1 / k) == int(i ** (1 / k)):

浮點數開根號有誤差,例如 Python 的 64 ** (1/3) 是 3.9999999999999996,跟 int(...) 比較會判斷成不是完全立方數。而且它在 [l, r] 裡逐一檢查,範圍到 10^9 一定太慢。

改成整數二分,但漏掉了 0
#

if n == 0:
    return 0
low = 1

二分從 1 開始,n == 0 也回傳 0,等於把 x = 0 排除了。l = 0 時,0 這個完全 k 次方數就被漏掉。改成從 0 開始、n < 0 時回傳 -1 就 AC 了。

隔天重寫:枚舉底數
#

改成枚舉 x 從 0 到 r^(1/k) + 1,檢查 l <= x^k <= r。k = 1 時 x 要枚舉到 10^9,TLE,加了 k == 1 的特判才過。

最後一版只用浮點數估計 x 的範圍,再用整數修正兩端,也 AC 了。

正確解法
#

class Solution:
    def countKthRoots(self, l: int, r: int, k: int) -> int:
        def floor_root(n: int) -> int:            # 最大的 x,使得 x ** k <= n
            lo, hi = 0, n + 1
            while lo < hi:
                mid = (lo + hi) // 2
                if mid ** k <= n:
                    lo = mid + 1
                else:
                    hi = mid
            return lo - 1                          # n < 0 時回傳 -1

        return floor_root(r) - floor_root(l - 1)

全程都是整數運算,k = 1 也不需要特判。

複雜度
#

時間 O(k log r):二分 log r 次,每次算 mid ** k。空間 O(1)。

要特別避免的錯誤
#

  • 用浮點數開根號再比較相等。
  • 漏掉 0:l = 0 時,0 本身就是完全 k 次方數。
  • 枚舉底數時沒考慮 k = 1:底數會多到 10^9 個。

面試口說整理
#

區間內的完全 k 次方數個數,等於 f(r) - f(l - 1),f(n) 是滿足 x^k <= n 的最大整數 x。浮點數開根號有誤差,所以我用整數二分算 f,從 0 開始搜尋,這樣 0 也會被算進去,而且 f(-1) 自然是 -1。時間 O(k log r)。

相關文章

LeetCode 633: Sum of Square Numbers
·2 分鐘
LeetCode Medium Two-Pointers Math Binary-Search
LeetCode 633 解題筆記:a 從 0、b 從 isqrt(c) 開始對撞;平方和太大 b 減一,太小 a 加一;注意 0 也算、a 可以等於 b、浮點數開根號的誤差
LeetCode 3824: Minimum K to Reduce Array Within Limit
·1 分鐘
LeetCode Medium Binary-Search Math
LeetCode 3824 解題筆記:對 k 二分,條件是單調的;上界至少要到 n,因為操作次數至少是 n
LeetCode 3918: Sum of Primes Between Number and Its Reverse
·1 分鐘
LeetCode Medium Math Number-Theory
LeetCode 3918 解題筆記:把 n 反轉,範圍是 [min, max],逐一試除判斷質數加總;判斷整除要用 %,不要比較 // 和 /
LeetCode 3899: Angles of a Triangle
·1 分鐘
LeetCode Medium Math Geometry
LeetCode 3899 解題筆記:先用三角不等式判斷能不能組成三角形,再用餘弦定理算三個角,記得排序
LeetCode 2563: Count the Number of Fair Pairs
·2 分鐘
LeetCode Medium Two-Pointers Sorting Binary-Search Array
LeetCode 2563 解題筆記:把「和落在 [lower, upper]」拆成「和 <= upper」減「和 <= lower - 1」,每個都用排序後的對撞指針 O(n) 數
LeetCode 1498: Number of Subsequences That Satisfy the Given Sum Condition
·2 分鐘
LeetCode Medium Two-Pointers Sorting Binary-Search Array
LeetCode 1498 解題筆記:子序列只看最小值和最大值,排序後順序無關;固定最小值 nums[left],中間的元素任意選,共 2^(right - left) 種