题目描述

思路

这道题就是在说,由多个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。

代码

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

package interview.google;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner; public class BeautifulNumber { public static void main(String[] args) {
Scanner in = new Scanner(
new BufferedReader(new InputStreamReader(System.in)));
int cases = in.nextInt();
for (int i = 1; i <= cases; ++i) {
long n = in.nextLong();
System.out.println("Case #" + i + ": "
+ beautiful(n));
}
} private static long beautiful(long n) {
for (long radix = 2; radix < n; radix++) {
if (isBeautiful(n, radix)) {
return radix;
}
} throw new IllegalStateException("Should not reach here.");
} private static boolean isBeautiful(long n, long radix) {
while (n > 0) {
if (n % radix != 1) {
return false;
}
n /= radix;
}
return true;
}
}

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

package interview.google;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner; public class BeautifulNumberLarge { public static void main(String[] args) {
Scanner in = new Scanner(
new BufferedReader(new InputStreamReader(System.in)));
int cases = in.nextInt();
for (int i = 1; i <= cases; ++i) {
long n = in.nextLong();
System.out.println("Case #" + i + ": "
+ beautiful(n));
}
} private static long beautiful(long n) {
for (int bits = 64; bits >= 2; bits--) {
long radix = getRadix(n, bits);
if (radix != -1) {
return radix;
}
} throw new IllegalStateException("Should not reach here.");
} /**
* Gets radix so that n is 111...1 (bits 1 in total) in that
* radix.二分查找,最大值需要+1.
*
* @return the radix. -1 if there's no such radix.
*/
private static long getRadix(long n, int bits) {
long minRadix = 2;
long maxRadix = n;
while (minRadix < maxRadix) {
long m = minRadix + (maxRadix - minRadix) / 2;
long t = convert(m, bits);
if (t == n) {
return m;
} else if (t < n) {
minRadix = m + 1;
} else {
maxRadix = m;
}
}
return -1;
} /**
* Returns the value of 111...1 (bits 1 in total) in radix.
*/
private static long convert(long radix, int bits) {
long component = 1;
long sum = 0;
for (int i = 0; i < bits; i++) {
if (Long.MAX_VALUE - sum < component) {
sum = Long.MAX_VALUE;
} else {
sum += component;
} if (Long.MAX_VALUE / component < radix) {
component = Long.MAX_VALUE;
} else {
component *= radix;
}
}
return sum;
}
}

[算法]谷歌笔试题: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. rational rose 2003完整汉化版 win7版

    下载链接:https://pan.baidu.com/s/1InpgNS_1-Rigw4fE3OX1Eg 软件介绍 Rational Rose 2003破解版是一款基于UML的可视化建模工具.可用于软 ...

  2. LogStash如何通过jdbc 从mysql导入elasticsearch

    input { stdin { } jdbc { # mysql jdbc connection string to our backup databse jdbc_connection_string ...

  3. 如何使用好android的可访问性服务(Accessibility Services)

    原文:http://android.eoe.cn/topic/android_sdk * 主题* Manifest声明和权限 可访问性服务声明 可访问性服务配置 AccessibilityServic ...

  4. eclipse CDT写c++使用文件作为输入源(输入重定向)

    在main函数第一句添加下面. freopen("inputfile","r",stdin); 创建一个inputfile,放project根文件夹下. 注意添 ...

  5. rpx

    rpx(responsive pixel): 可以根据屏幕宽度进行自适应.规定屏幕宽为750rpx.如在iPhone6上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = ...

  6. 【Android】1.2 创建Android模拟器

    分类:C#.Android.VS2015:  创建日期:2016-01-20 调试手机应用程序一般先用模拟器来实现,只是因为每次都发布到手机上调试太麻烦了.当应用程序在模拟器上调试没错后,再发布到手机 ...

  7. 趣味讲解:移动互联网 VS 传统互联网

    趣味讲解:移动互联网 VS 传统互联网 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转 ...

  8. 深入详解JVM内存模型与JVM参数详细配置

    对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...

  9. git(8):常用命令

    Git常用操作命令收集: 1) 远程仓库相关命令 检出仓库:$ git clone git://github.com/jquery/jquery.git 查看远程仓库:$ git remote -v ...

  10. VS生成后事件对文件的copy以及更换扩展名

    在VC++2012的项目里,属性内有生成事件. 可以用后期生成事件命令行做一些生成之后的事情,比如对编译出的.dll,.lib,.pdb等文件进行copy或者更改扩展名. 我用到的就是将和项目同名的. ...