leetcode题解-483. Smallest Good Base
来源:互联网 发布:高管都用什么手机 数据 编辑:程序博客网 时间:2024/05/18 18:01
题目:
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 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.
本题是寻找一个数最小的good base。其定义是对于一个数y,其x进制表示为全1,则称x是y的good base。应该比较好理解,其实就是将y写成1+x+x^2+...+x^(n-1)
,就是一个等比数列求和,于是我们可以将其转化为y = (x^n - 1)/(x - 1)
,其中x>=2, 3<y<10^18
,为了寻找最小的x,我们可以先来确定一下n的取值范围,很明显x越小n越大,所以当x=2时,n最大为log2(y+1)
。从第三个例子可以看出来,当x=y-1时,n最小为2。所以有了n的取值范围我们就可以遍历所有可能的n,然后每次循环中y和n都是确定值,在对x使用二叉搜索确定其值即可。
另外一个需要注意的问题就是,因为本题中的数都比较大,所以要注意溢出问题,之前也做过一到这种题,可以使用java内置的BigInteger类进行处理。代码如下所示:
public static String smallestGoodBase(String n) { //现将字符串解析成long型数据 long s = Long.parseLong(n); //对所有可能的指数n进行遍历 for(int max_e=(int)(Math.log(s)/Math.log(2)) + 1; max_e>=2; max_e--){ long low=2, high=s, mid; //进行二叉搜索,寻找最小的good base。 while(low <= high){ mid = low + (high - low)/2; //一开始没有使用BigInteger,会报错 BigInteger left = BigInteger.valueOf(mid); left = left.pow(max_e).subtract(BigInteger.ONE); BigInteger right = BigInteger.valueOf(s).multiply(BigInteger.valueOf(mid).subtract(BigInteger.ONE)); int cmr = left.compareTo(right); if(cmr == 0) return String.valueOf(mid); else if(cmr > 0) high = mid - 1; else low = mid + 1; } } return String.valueOf(s-1); }
上面这种方法效率比较低,还在网上找到了下面这种解决方案,首先说前面三行,一个是使用内置方法将字符串转化为long型整数,一个是写循环,测试结果发现第二种效果更好==,其次使用这种方法可以击败98%的用户,原因是其在二叉搜索的过程中的上限取的是Math.pow(num, 1.0/p) + 1
,相比num本身小了很多,所以大大节省了时间。
public String smallestGoodBase1(String n) { long num = 0; for (char c : n.toCharArray()) num = num * 10 + c - '0'; //long num = Long.parseLong(n); long x = 1; for (int p = 64; p >= 1; p--) { if ((x << p) < num) { long k = helper(num, p); if (k != -1) return String.valueOf(k); } } return String.valueOf(num - 1); } private long helper(long num, int p) { long l = 1, r = (long)(Math.pow(num, 1.0/p) + 1); while (l < r) { long mid = l + (r - l) / 2; long sum = 0, cur = 1; for (int i = 0; i <= p; i++) { sum += cur; cur *= mid; } if (sum == num) return mid; else if (sum > num) r = mid; else l = mid + 1; } return -1; }
阅读全文
0 0
- leetcode题解-483. Smallest Good Base
- LeetCode 483 Smallest Good Base 题解
- leetCode 483. Smallest Good Base
- [leetcode]483. Smallest Good Base
- [Leetcode] 483. Smallest Good Base 解题报告
- leetcode 483. Smallest Good Base 二分查找
- 483. Smallest Good Base
- 483. Smallest Good Base
- 483. Smallest Good Base
- 483. Smallest Good Base
- 483. Smallest Good Base
- LeetCode 483 Smallest Good Base 解题报告
- Smallest Good Base
- Leetcode 483 - Smallest Good Base(二分+枚举)
- leetcode483. Smallest Good Base 的一些思考
- leetcode题解 632. Smallest Range
- LeetCode 题解(284) : Smallest Rectangle Enclosing Black Pixels
- LeetCode题解:Kth Smallest Element in a BST
- javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
- 在文件中查找特定的字符串方法 grep命令
- Android客制化------禁止系统下载apk文件
- URL编解码
- 使用位移动画实现跑马灯效果
- leetcode题解-483. Smallest Good Base
- 《设计模式之禅》第二版 学习之六大设计原则(一)
- 进程学习:进程间通信(基础知识篇)
- Android support.v7库包含控件解析
- 关于elasticsearch的几个QueryBuilder
- 写给Krpano小白们的最最最入门级教程(一)
- Java8 Stream的分组,分区
- Jzoj5440 【NOIP2017提高A组冲刺11.1】背包
- 应怎样看待 target="_blank" 的使用?