leetcode-483-最小好进制
[博客链接]
[题目描述]
对于给定的整数 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。
Related Topics 数学 二分查找
👍 65 👎 0
[题目链接]
[github地址]
[思路介绍]
思路一:等比数列求和公式
- (q是公比 n是s转换成q进制后1的个数)
- n越大q越小n最大不超过**(s-1)**
- 因为s一定可以转换成s-1进制的好进制格式即11
- 因为求的是最小好进制
- 所以可以从最小公比开始遍历遍历范围**[2,s-1]**标识为公比
- 从i= 2开始推出tempT = s*(i-1)+1
- 判断tempT的最大这种方法会TLE
public String smallestGoodBase(String s) {
long target = Long.parseLong(s);
for (long i = 2; i < target; i++) {
long tempT = target * (i - 1) + 1;
//排除不满足的i情况
if (tempT % i != 0) {
continue;
}
//判断是否能够满足tempT是i的n次幂
while (tempT % i == 0 && tempT != i) {
tempT /= i;
}
if (tempT == i) {
return String.valueOf(i);
}
}
return String.valueOf(target - 1);
}
时间复杂度O(n*logn)
思路二:思路一+不等式推倒
- 思路一确定有解
- 再根据二项式定理(官方题解可以推出i = 的下线整数)
- 根据n从最大值开始枚举满足条件的i的数,第一个遇到的即为k的最小值(n标识i进制位数)
public String smallestGoodBase(String s) {
long nVal = Long.parseLong(s);
int mMax = (int) Math.floor(Math.log(nVal) / Math.log(2));
for (int n = mMax; n > 1; n--) {
int i = (int) Math.pow(nVal, 1.0 / n);
long mul = 1, sum = 1;
for (int t = 0; t < n; t++) {
mul *= i;
sum += mul;
}
if (sum == nVal) {
return Integer.toString(i);
}
}
return Long.toString(nVal - 1);
}
时间复杂度(O())