0
点赞
收藏
分享

微信扫一扫

LeetCode #483 Smallest Good Base 最小好进制

攻城狮Chova 2021-09-21 阅读 73

483 Smallest Good Base 最小好进制

Description:
For an integer n, we call k>=2 a good base of n, if all digits of n base k are 1.

Now given a string representing n, you should return the smallest good base of n in string format.

Example:

Example 1:

Input: "13"
Output: "3"
Explanation: 13 base 3 is 111.

Example 2:

Input: "4681"
Output: "8"
Explanation: 4681 base 8 is 11111.

Example 3:

Input: "1000000000000000000"
Output: "999999999999999999"
Explanation: 1000000000000000000 base 999999999999999999 is 11.

Note:

The range of n is [3, 10^18].
The string representing n is always valid and will not have leading zeros.

题目描述:
对于给定的整数 n, 如果n的k(k>=2)进制数的所有数位全为1,则称 k(k>=2)是 n 的一个好进制。

以字符串的形式给出 n, 以字符串的形式返回 n 的最小好进制。

示例 :

示例 1:

输入:"13"
输出:"3"
解释:13 的 3 进制是 111。

示例 2:

输入:"4681"
输出:"8"
解释:4681 的 8 进制是 11111。

示例 3:

输入:"1000000000000000000"
输出:"999999999999999999"
解释:1000000000000000000 的 999999999999999999 进制是 11。

提示:

n的取值范围是 [3, 10^18]。
输入总是有效且没有前导 0。

思路:

假设这个数为 k进制, 一共长为 m
n = k ^ (m - 1) + k ^ (m - 2) + ... + k + 1 = k ^ m - 1 / (k - 1)
当这个数为 2进制时, m能取到最大值, 最小值为 2
可以用二分法加快搜索
时间复杂度O(nlglgn), 空间复杂度O(1)

代码:
C++:

class Solution 
{
public:
    string smallestGoodBase(string n) 
    {
        long num = stol(n);
        for (int m = (int)(log(num + 1) / log(2)); m >= 2; m--) 
        {
            long left = 2, right = (long)pow(num, 1.0 / (m - 1)) + 1;
            while (left < right) 
            {
                long mid = left + ((right - left) >> 1), sum = 0;
                for (int j = 0; j < m; j++) sum = sum * mid + 1;
                if (sum == num) return to_string(mid);
                else if (sum < num) left = mid + 1;
                else right = mid;
            }
        }
        return to_string(num - 1);
    }
};

Java:

class Solution {
    public String smallestGoodBase(String n) {
        long num = Long.parseLong(n);
        for (int m = (int)(Math.log(num + 1) / Math.log(2)); m >= 2; m--) {
            long left = 2, right = (long)Math.pow(num, 1.0 / (m - 1)) + 1;
            while (left < right) {
                long mid = left + ((right - left) >> 1), sum = 0;
                for (int j = 0; j < m; j++) sum = sum * mid + 1;
                if (sum == num) return String.valueOf(mid);
                else if (sum < num) left = mid + 1;
                else right = mid;
            }
        }
        return String.valueOf(num - 1);
    }
}

Python:

class Solution:
    def smallestGoodBase(self, n: str) -> str:
        num = int(n)
        for m in range(num.bit_length(), 2, -1):
            x = int(num ** (1 / (m - 1)))
            if num == (x ** m - 1) // (x - 1):
                return str(x)
        return str(num - 1)
举报

相关推荐

0 条评论