Leetcode---483最小好进制

今天又是困难题,不会做,在看官方题解和其他人的题解终于明白了,记录一下。

483最小好进制

在这里插入图片描述

思路

做题前的分析:

  1. 因为n的范围为 3 ≤ n ≤ 1 0 18 3\le n \le 10^{18} 3n1018,上限远远超过1e7,所以不能使用暴力方法;
  2. 因为java中的long的范围最大为 2 63 − 1 2^{63}-1 2631 大于 1 0 18 10^{18} 1018 ,所以可以使用long类型的变量转存n,方便进行计算;
  3. 由题意和示例可以分析得出,最终的答案k的值范围在 2 ≤ k ≤ ( n − 1 ) 2\le k \le (n-1) 2k(n1)
  4. k = 2 、 n = 1 0 18 k=2、n=10^{18} k=2n=1018时,如果满足条件,答案不会超过60,又因为 k ≠ n , k ≠ 1 k \ne n,k\ne 1 k=nk=1,所以答案的范围在 2 ≤ l e n ≤ 60 2\le len \le 60 2len60,一般情况下为 2 ≤ l e n ≤ l o g 2 ( n ) 2\le len \le log_2(n) 2lenlog2(n)
  5. n = k 0 + k 1 + . . . . + k m n=k^0+k^1+....+k^m n=k0+k1+....+km时,可得 n > k m n>k^m n>km,由二项式定理 k m < n < k m + 1 k^m < n < k^{m+1} km<n<km+1,所以 k < n 1 m < k + 1 k<n^{\frac{1}{m}}<k+1 k<nm1<k+1,其中m为正整数;

代码

class Solution {
    public String smallestGoodBase(String n) {
        //因为n的值最大为10的18次方,小于2的63次方-1,所以可以使用long转存
        long num = Long.parseLong(n);
        //通过分析,发现len的值在2-60,k的值在2-(n-1)
        int maxLen = (int)(Math.log(1.0 * num) / Math.log(2.0));

        for (int len = 2; len<=maxLen;len++)
        {
            //获取k
            long k = (long)Math.pow(num,1.0/len);
            if (countNum(k,len)==num)
                return String.valueOf(k);
        }

        return String.valueOf(num-1);
    }
    public long countNum(long k, int len)
    {
        long sum = 1;
        //计算k的0至(len-1)次方的和+1
        //每一次的sum都是k的0至(i-1)次方的和+1
        //即在k进制下(i+1)个1对应的十进制数
        for (int i=0;i<len;i++)
            sum = sum * k + 1;
        return sum;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值