题目描述

思路

这道题就是在说,由多个1组成的数是beautiful的,现在想求出r进制中的r,使得给出的数字转换成r进制,得到beautiful的数字,如果有多种方式转换,那么取1的个数最多的那种情况,也就是r最小的情况。

这道题其实就是10进制和r进制的转化,这里就不详述了,但是注意题目中的一点就是给了两种数据集,小数据集的N最大为1000,大数据集的N最大为10^18,大数据集非常棘手。

先看看小数据集的常规思路,就从二进制开始进行循环,每次循环判断一下该进制下进行转换得到的数字是否为beautiful的,见下面第一个代码。这种思路的时间复杂度是NlogN,因为N最大为1000,所以很快。

再看看大数据集,如果我们采用上面那种方式的话,N为10^18,这样带进去差不多是64*10^18的计算,假设计算机1秒执行10^8次计算,这样的耗时也是非常巨大的。

因此对于大数据集的思路是,我们先看一下,10^18的数字,转成二进制,最多的话,也是64个1,所以我们就设开始是64个1,然后递减,计算每次该个数的1能不能由某一进制转换成功。在计算进制的过程中,可以采用二分查找,这样总共的时间复杂度就是logN*logN*logN,相当于64*64*64,还是非常小的。最后因为可能数据溢出,所以用long,用long也可能在计算过程中溢出,所以做了一下处理,这里同样可以采用BigInteger。

代码

小数据集的代码(常规思路):

  1. package interview.google;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.InputStreamReader;
  5. import java.util.Scanner;
  6.  
  7. public class BeautifulNumber {
  8.  
  9. public static void main(String[] args) {
  10. Scanner in = new Scanner(
  11. new BufferedReader(new InputStreamReader(System.in)));
  12. int cases = in.nextInt();
  13. for (int i = 1; i <= cases; ++i) {
  14. long n = in.nextLong();
  15. System.out.println("Case #" + i + ": "
  16. + beautiful(n));
  17. }
  18. }
  19.  
  20. private static long beautiful(long n) {
  21. for (long radix = 2; radix < n; radix++) {
  22. if (isBeautiful(n, radix)) {
  23. return radix;
  24. }
  25. }
  26.  
  27. throw new IllegalStateException("Should not reach here.");
  28. }
  29.  
  30. private static boolean isBeautiful(long n, long radix) {
  31. while (n > 0) {
  32. if (n % radix != 1) {
  33. return false;
  34. }
  35. n /= radix;
  36. }
  37. return true;
  38. }
  39. }

大数据集的代码(同样适用于小数据集):

  1. package interview.google;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.InputStreamReader;
  5. import java.util.Scanner;
  6.  
  7. public class BeautifulNumberLarge {
  8.  
  9. public static void main(String[] args) {
  10. Scanner in = new Scanner(
  11. new BufferedReader(new InputStreamReader(System.in)));
  12. int cases = in.nextInt();
  13. for (int i = 1; i <= cases; ++i) {
  14. long n = in.nextLong();
  15. System.out.println("Case #" + i + ": "
  16. + beautiful(n));
  17. }
  18. }
  19.  
  20. private static long beautiful(long n) {
  21. for (int bits = 64; bits >= 2; bits--) {
  22. long radix = getRadix(n, bits);
  23. if (radix != -1) {
  24. return radix;
  25. }
  26. }
  27.  
  28. throw new IllegalStateException("Should not reach here.");
  29. }
  30.  
  31. /**
  32. * Gets radix so that n is 111...1 (bits 1 in total) in that
  33. * radix.二分查找,最大值需要+1.
  34. *
  35. * @return the radix. -1 if there's no such radix.
  36. */
  37. private static long getRadix(long n, int bits) {
  38. long minRadix = 2;
  39. long maxRadix = n;
  40. while (minRadix < maxRadix) {
  41. long m = minRadix + (maxRadix - minRadix) / 2;
  42. long t = convert(m, bits);
  43. if (t == n) {
  44. return m;
  45. } else if (t < n) {
  46. minRadix = m + 1;
  47. } else {
  48. maxRadix = m;
  49. }
  50. }
  51. return -1;
  52. }
  53.  
  54. /**
  55. * Returns the value of 111...1 (bits 1 in total) in radix.
  56. */
  57. private static long convert(long radix, int bits) {
  58. long component = 1;
  59. long sum = 0;
  60. for (int i = 0; i < bits; i++) {
  61. if (Long.MAX_VALUE - sum < component) {
  62. sum = Long.MAX_VALUE;
  63. } else {
  64. sum += component;
  65. }
  66.  
  67. if (Long.MAX_VALUE / component < radix) {
  68. component = Long.MAX_VALUE;
  69. } else {
  70. component *= radix;
  71. }
  72. }
  73. return sum;
  74. }
  75. }

[算法]谷歌笔试题:Beautiful Numbers的更多相关文章

  1. 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。

    谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数. Google2009华南地 ...

  2. 谷歌笔试题——排序,只允许0和其他元素交换

    2.2 长度为n的数组乱序存放着0至n-1. 现在只能进行0与其他数的swap,请设计并实现排序. 这题有一个隐含条件:即数组元素是连续的,即0--n-1,当你排好序后,你会发现数组元素和该元素的下标 ...

  3. [算法]滴滴笔试题——求最大子串和(O(n)复杂度)

    扫描法.一次扫描数组即可得出答案,复杂度O(n).这种方法用文字描述不容易说清楚,下面用每一步运算的图示来表达.伪代码如下: maxsofar=end=; ,n) end=max(end+x[i],) ...

  4. Java工程师笔试题整理[校招篇]

    Java工程师笔试题整理[校招篇]     隔着两个月即将开始校招了.你是不是也想借着这个机会崭露头角,拿到某些大厂的offer,赢取白富美.走上人生巅峰?当然如果你还没能打下Java基础,一定要先打 ...

  5. 算法笔试题整理——升级蓄水池 && 字符串数字表达式计算值 && 求旅游完所有景点需要的最少天数 && 宝箱怪

    1. 小米笔试题——升级蓄水池 题目描述: 在米兔生活的二维世界中,建造蓄水池非常简单. 一个蓄水池可以用n个坐标轴上的非负整数表示,代表区间为[0-n]范围内宽度为1的墙壁的高度. 如下图1,黑色部 ...

  6. UC算法笔试题

    说实话,昨天UC的笔试题基本全是基础,但是太基础,直接导致很多都不能确定了.看来不管找工作还是找实习,一定要复习到位.好在我也一直是抱着打酱油的味道,实习与否不是特别在意,否则真心要鄙视死自己啦. 好 ...

  7. 算法题14 小Q歌单,牛客网,腾讯笔试题

    算法题14 小Q歌单,牛客网,腾讯笔试题 题目: 小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌 ...

  8. 算法题16 贪吃的小Q 牛客网 腾讯笔试题

    算法题16 贪吃的小Q 牛客网 腾讯笔试题 题目: 链接:https://www.nowcoder.com/questionTerminal/d732267e73ce4918b61d9e3d0ddd9 ...

  9. acwing 算法面试、笔试题公开课整理记录

    week1 Google KickStart 2019 A轮 讲解视频地址AcWing 549. 训练   tag: 排序 遍历 在线练习地址AcWing 550. 包裹       在线练习地址Ac ...

随机推荐

  1. 第一篇:初识ASP.NET控件开发_第三节:“生死有序”的控件生命周期

    一.Page本质是一个Control 我们首先要澄清的第一个概念是页面类Page本质是一个控件类,它派生于TemplateControl类,而TemplateControl派生自Control类.既然 ...

  2. Java多线程框架Executor详解

       原文链接  http://www.imooc.com/article/14377 为什么引入Executor线程池框架new Thread()的缺点 每次new Thread()耗费性能调用ne ...

  3. 清理kafka zookeeper

    ; ; /; rm -rf /app/zookeeper/logs/*; rm -rf /app/pet_kafka_emds2_cluster/kafka-logs/*; rm -rf /app/p ...

  4. UI控件篇——UIPageControl及其自定义

    UIPageControl类提供一行点来指示当前显示的是多页面视图的哪一页.当然,由于UIPageControl类可视样式的点击不太好操作,所以最好是确保再添加了可选择的导航选项,以便让页面控件看起来 ...

  5. 深入理解Linux内核-内核同步

    内核基本的同步机制: 抢占内核的主要特点:一个在内核态运行的进程,可能在执行内核函数期间被另外一个进程取代. 内核抢占:Linux 2.6允许用户在编译内核的时候配置十分启用 进程临界区:每个进程中访 ...

  6. 解决code::blocks 17.12不能debug的方法

    错误提示: You need to specify a debugger program in the debuggers's settings. 解决方法: 在settings->debugg ...

  7. linux系统查毒软件ClamAV

    安装方法: 长久使用参考: http://www.cnblogs.com/kerrycode/archive/2015/08/24/4754820.html#undefined 临时使用参考: htt ...

  8. [Windows Azure] How to use the Table Storage Service

    How to use the Table Storage Service version 1.7 version 2.0 This guide will show you how to perform ...

  9. Linux服务开机自启动使用示例

    本文以redis服务为例,介绍了两种服务自启动的方法service,systemctl使用示例 1.修改redis.conf,允许后台运行 daemonize no 改为 daemonize yes ...

  10. 每日英语:Nelson Mandela Dies at 95

    Nelson Mandela, who rose from militant antiapartheid activist to become the unifying president of a ...