[算法]谷歌笔试题:Beautiful Numbers
题目描述
思路
这道题就是在说,由多个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的更多相关文章
- 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数. Google2009华南地 ...
- 谷歌笔试题——排序,只允许0和其他元素交换
2.2 长度为n的数组乱序存放着0至n-1. 现在只能进行0与其他数的swap,请设计并实现排序. 这题有一个隐含条件:即数组元素是连续的,即0--n-1,当你排好序后,你会发现数组元素和该元素的下标 ...
- [算法]滴滴笔试题——求最大子串和(O(n)复杂度)
扫描法.一次扫描数组即可得出答案,复杂度O(n).这种方法用文字描述不容易说清楚,下面用每一步运算的图示来表达.伪代码如下: maxsofar=end=; ,n) end=max(end+x[i],) ...
- Java工程师笔试题整理[校招篇]
Java工程师笔试题整理[校招篇] 隔着两个月即将开始校招了.你是不是也想借着这个机会崭露头角,拿到某些大厂的offer,赢取白富美.走上人生巅峰?当然如果你还没能打下Java基础,一定要先打 ...
- 算法笔试题整理——升级蓄水池 && 字符串数字表达式计算值 && 求旅游完所有景点需要的最少天数 && 宝箱怪
1. 小米笔试题——升级蓄水池 题目描述: 在米兔生活的二维世界中,建造蓄水池非常简单. 一个蓄水池可以用n个坐标轴上的非负整数表示,代表区间为[0-n]范围内宽度为1的墙壁的高度. 如下图1,黑色部 ...
- UC算法笔试题
说实话,昨天UC的笔试题基本全是基础,但是太基础,直接导致很多都不能确定了.看来不管找工作还是找实习,一定要复习到位.好在我也一直是抱着打酱油的味道,实习与否不是特别在意,否则真心要鄙视死自己啦. 好 ...
- 算法题14 小Q歌单,牛客网,腾讯笔试题
算法题14 小Q歌单,牛客网,腾讯笔试题 题目: 小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌 ...
- 算法题16 贪吃的小Q 牛客网 腾讯笔试题
算法题16 贪吃的小Q 牛客网 腾讯笔试题 题目: 链接:https://www.nowcoder.com/questionTerminal/d732267e73ce4918b61d9e3d0ddd9 ...
- acwing 算法面试、笔试题公开课整理记录
week1 Google KickStart 2019 A轮 讲解视频地址AcWing 549. 训练 tag: 排序 遍历 在线练习地址AcWing 550. 包裹 在线练习地址Ac ...
随机推荐
- 第一篇:初识ASP.NET控件开发_第三节:“生死有序”的控件生命周期
一.Page本质是一个Control 我们首先要澄清的第一个概念是页面类Page本质是一个控件类,它派生于TemplateControl类,而TemplateControl派生自Control类.既然 ...
- Java多线程框架Executor详解
原文链接 http://www.imooc.com/article/14377 为什么引入Executor线程池框架new Thread()的缺点 每次new Thread()耗费性能调用ne ...
- 清理kafka zookeeper
; ; /; rm -rf /app/zookeeper/logs/*; rm -rf /app/pet_kafka_emds2_cluster/kafka-logs/*; rm -rf /app/p ...
- UI控件篇——UIPageControl及其自定义
UIPageControl类提供一行点来指示当前显示的是多页面视图的哪一页.当然,由于UIPageControl类可视样式的点击不太好操作,所以最好是确保再添加了可选择的导航选项,以便让页面控件看起来 ...
- 深入理解Linux内核-内核同步
内核基本的同步机制: 抢占内核的主要特点:一个在内核态运行的进程,可能在执行内核函数期间被另外一个进程取代. 内核抢占:Linux 2.6允许用户在编译内核的时候配置十分启用 进程临界区:每个进程中访 ...
- 解决code::blocks 17.12不能debug的方法
错误提示: You need to specify a debugger program in the debuggers's settings. 解决方法: 在settings->debugg ...
- linux系统查毒软件ClamAV
安装方法: 长久使用参考: http://www.cnblogs.com/kerrycode/archive/2015/08/24/4754820.html#undefined 临时使用参考: htt ...
- [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 ...
- Linux服务开机自启动使用示例
本文以redis服务为例,介绍了两种服务自启动的方法service,systemctl使用示例 1.修改redis.conf,允许后台运行 daemonize no 改为 daemonize yes ...
- 每日英语:Nelson Mandela Dies at 95
Nelson Mandela, who rose from militant antiapartheid activist to become the unifying president of a ...