`

A Google's Interview Question - GLAT #20 series 3

阅读更多
The roadmap to compute all fixed points of f(x) is to start from boundaries 1, or 10^10, and keep acting f on it. If x is a boundary point, first compare x and f(x) to see whether we should generate the series using f or f inverse. Once we know which one to use, then keep doing that until we get a fixed point. Then start from the next integer again.

In order to do these, we need a few functions:
1. function f:
java 代码
  1. private long numOfOnes(long x)
  2. {
  3.     // recursion stops
  4.     if (x <= 0) return 0;
  5.     if (x == 1) return 1;
  6.     int powerk = 0;
  7.     long tenPowers = 1;
  8.     long leadingDigit = x;
  9.     while (leadingDigit >= 10)
  10.     {
  11.         leadingDigit /= 10;
  12.         powerk++;
  13.         tenPowers *= 10;
  14.     }
  15.     long reminder = x - leadingDigit * tenPowers;
  16.     if (leadingDigit == 1)
  17.     {
  18.         return powerk * tenPowers / 10 + 1 + reminder + numOfOnes(reminder);
  19.     }
  20.     else
  21.     {
  22.         return leadingDigit * powerk * tenPowers / 10 + tenPowers + numOfOnes(reminder);
  23.     }
  24. }

This is basically a direct translate of the formula (A) and (B) in Lemma 4.

2. inverse of f:
Obviously the next one is f inverse. Since f is not single valued, we have to have a better definition on the inverse. We define the inverse of f for a given y as the smallest x such that x < y <= f(x), so we could step as far as possible.
java 代码
  1. public long inverseFunc(long y)
  2. {
  3.     // recursion default.
  4.     if (y <= 0) return 0;
  5.     if (y == 1) return 1;
  6.     if (y == 2) return 10;
  7.     // check whether y is in 1's range
  8.     int m = isInOneRange(y);
  9.     if (m != -1)
  10.     {
  11.         long tmp = y - (m + 1) * power(10, m) - 1;
  12.         long inc = findRoot(tmp);
  13.         return power(10, m + 1) + inc;
  14.     }
  15.     else
  16.     {
  17.         int k = numOfDigits(y) - 1;
  18.         long tmp = y - power(10, k);
  19.         long ak = tmp / (k * power(10, k - 1));
  20.         if (ak > 9) ak = 9; // leave the rest to the recursion
  21.         long remainder = tmp - ak * k * power(10, k - 1);
  22.         long xRemainder = inverseFunc(remainder);
  23.         return ak * power(10, k) + xRemainder;
  24.     }
  25. }

The tricky part here is to figure out the power k. Here in order to know whether we should use formula (A) or (B), we need to check whether the to-be-found x has leading 1. So the helper function is
java 代码
  1. private int isInOneRange(long y)
  2. {
  3. // This is to check whether the func value is between the function
  4. // values of 10^n and 2*10^n.
  5. // this can be done faster since it's sorted, but again I am lazy
  6. int k=-1;
  7. for (int i=0; i<9; i++)
  8. {
  9. if (y <= y2[i])
  10. {
  11. k = i;
  12. break; // first smaller, break out
  13. }
  14. }
  15. if (k==-1) return -1;
  16. if (y >= y1[k]) return k;
  17. else return -1;
  18. }

where we define the following
java 代码
  1. long[] x1 = new long[9];
  2. long[] x2 = new long[9];
  3. long[] y1 = new long[9];
  4. long[] y2 = new long[9];
  5. for (int i=1; i<10; i++)
  6. {
  7. x1[i-1] = power(10, i);
  8. x2[i-1] = 2 * x1[i-1] - 1;
  9. y1[i-1] = numOfOnes(x1[i-1]);
  10. y2[i-1] = numOfOnes(x2[i-1]);
  11. }
  12. If we print out them:
  13. x range=[10, 19] y range=[2, 12]
  14. x range=[100, 199] y range=[21, 140]
  15. x range=[1000, 1999] y range=[301, 1600]
  16. x range=[10000, 19999] y range=[4001, 18000]
  17. x range=[100000, 199999] y range=[50001, 200000]
  18. x range=[1000000, 1999999] y range=[600001, 2200000]
  19. x range=[10000000, 19999999] y range=[7000001, 24000000]
  20. x range=[100000000, 199999999] y range=[80000001, 260000000]
  21. x range=[1000000000, 1999999999] y range=[900000001, 2800000000]

The other missing piece is the function foundRoot(). This is used in formula (A), which can be simplified in the form x + f(x) = y, with unknown x. We need a function to find the root x.
java 代码
  1. public long findRoot(long y)
  2. {
  3. // find a root for x + f(x) = y, where f is the number of one's function
  4. // in the above.
  5. // we need a x such that x + f(x)>=y, the largest x.
  6. // Note that x + f(x) is a mononically increasing function.
  7. long x0 = 0;
  8. long x1 = y;
  9. long x;
  10. while (x1 - x0 > 1)
  11. {
  12. x = x0 + (x1 - x0) / 2;
  13. long func = numOfOnes(x) + x;
  14. if (func == y) return x;
  15. if (func < y)
  16. {
  17. x0 = x;
  18. }
  19. else
  20. {
  21. x1 = x;
  22. }
  23. }
  24. if (x0 + numOfOnes(x0) == y) return x0;
  25. else return x1;
  26. }

Two other small functions are:
java 代码
  1. private static int numOfDigits(long x)
  2. {
  3. int i = 0;
  4. while (x > 0)
  5. {
  6. x /= 10;
  7. i++;
  8. }
  9. return i;
  10. }

which computes the number of 1's in x, and
java 代码
  1. private static long power(long base, int power)
  2. {
  3. long ret = 1;
  4. for (int i=1; i<=power; i++) ret *= base;
  5. return ret;
  6. }

which computes the power for the performance reason. With all of these in places, the only thing left is a "conductor" method:
java 代码
  1. public void countDigitOne()
  2. {
  3. long begin = System.currentTimeMillis();
  4. long loop = 10000000000L;
  5. int iterationTimes = 1;
  6. while (loop > 0 && iterationTimes < ITERATION_LIMIT)
  7. {
  8. long func = numOfOnes(loop);
  9. if (func == loop)
  10. {
  11. System.out.println("-----> found a fixed point: x=" + loop);
  12. // now skip this one and keep going for the next one.
  13. loop--;
  14. }
  15. else
  16. {
  17. if (func < loop) // we force this to go to the left.
  18. {
  19. loop = func;
  20. }
  21. else // func > loop
  22. {
  23. func = inverseFunc(loop);
  24. if (func < loop && numOfOnes(func) >= loop)
  25. {
  26. loop = func;
  27. }
  28. else
  29. {
  30. loop --; // if we can't find one, just decrement it.
  31. }
  32. }
  33. }
  34. iterationTimes++;
  35. }
  36. System.out.println("It takes " + (System.currentTimeMillis() - begin) + " milli");
  37. System.out.println("It takes " + iterationTimes + " iterations");
  38. }

The result is:

-----> found a fixed point: x=1111111110
-----> found a fixed point: x=535200001
-----> found a fixed point: x=535200000
-----> found a fixed point: x=535199990
-----> found a fixed point: x=535199989
-----> found a fixed point: x=535199988
-----> found a fixed point: x=535199987
-----> found a fixed point: x=535199986
-----> found a fixed point: x=535199985
-----> found a fixed point: x=535199984
-----> found a fixed point: x=535199983
-----> found a fixed point: x=535199982
-----> found a fixed point: x=535199981
-----> found a fixed point: x=535000001
-----> found a fixed point: x=535000000
-----> found a fixed point: x=513199998
-----> found a fixed point: x=502600001
-----> found a fixed point: x=502600000
-----> found a fixed point: x=501599990
-----> found a fixed point: x=501599989
-----> found a fixed point: x=501599988
-----> found a fixed point: x=501599987
-----> found a fixed point: x=501599986
-----> found a fixed point: x=501599985
-----> found a fixed point: x=501599984
-----> found a fixed point: x=501599983
-----> found a fixed point: x=501599982
-----> found a fixed point: x=501599981
-----> found a fixed point: x=500200001
-----> found a fixed point: x=500200000
-----> found a fixed point: x=500199990
-----> found a fixed point: x=500199989
-----> found a fixed point: x=500199988
-----> found a fixed point: x=500199987
-----> found a fixed point: x=500199986
-----> found a fixed point: x=500199985
-----> found a fixed point: x=500199984
-----> found a fixed point: x=500199983
-----> found a fixed point: x=500199982
-----> found a fixed point: x=500199981
-----> found a fixed point: x=500000001
-----> found a fixed point: x=500000000
-----> found a fixed point: x=117463825
-----> found a fixed point: x=35200001
-----> found a fixed point: x=35200000
-----> found a fixed point: x=35199990
-----> found a fixed point: x=35199989
-----> found a fixed point: x=35199988
-----> found a fixed point: x=35199987
-----> found a fixed point: x=35199986
-----> found a fixed point: x=35199985
-----> found a fixed point: x=35199984
-----> found a fixed point: x=35199983
-----> found a fixed point: x=35199982
-----> found a fixed point: x=35199981
-----> found a fixed point: x=35000001
-----> found a fixed point: x=35000000
-----> found a fixed point: x=13199998
-----> found a fixed point: x=2600001
-----> found a fixed point: x=2600000
-----> found a fixed point: x=1599990
-----> found a fixed point: x=1599989
-----> found a fixed point: x=1599988
-----> found a fixed point: x=1599987
-----> found a fixed point: x=1599986
-----> found a fixed point: x=1599985
-----> found a fixed point: x=1599984
-----> found a fixed point: x=1599983
-----> found a fixed point: x=1599982
-----> found a fixed point: x=1599981
-----> found a fixed point: x=200001
-----> found a fixed point: x=200000
-----> found a fixed point: x=199990
-----> found a fixed point: x=199989
-----> found a fixed point: x=199988
-----> found a fixed point: x=199987
-----> found a fixed point: x=199986
-----> found a fixed point: x=199985
-----> found a fixed point: x=199984
-----> found a fixed point: x=199983
-----> found a fixed point: x=199982
-----> found a fixed point: x=199981
-----> found a fixed point: x=1
It takes 62 milli
It takes 1139 iterations.

This is a typical fixed point problem, start from some arbitrary number and keep acting f on it. Several outputs of the series are:
1. It goes to infinity.
2. It goes to some fixed point.
3. It keeps bouncing back and forth(going nowhere).

Two types of fixed points are attractors and opposite attractors. Attractors are attracting nearby points, i.e., if we start from some point "close" enough to the attractor, the series will converge to the attractor. Opposite attractor is just the opposite, the series will go away from the opposite attractor.
分享到:
评论

相关推荐

    2023年5月的大众点评成都市酒店店铺信息数据,5w余家,包括星级酒店和民宿旅馆 最新的我也有

    C1iS5txWz9vBs0tu 冲天De跳蚤的民宿(成都站店) 0 0 0 0 0 冲天De跳蚤的民宿 成都站店 府青路20号中房蓝水湾@#3栋2单元501 181081383** 30.6861 104.099 民宿 民宿 酒店 33841 火车北站/高笋塘 成华区 7762 38 ...

    idl代码与Matlab-NCAR-GLOW:CMake,Meson,Matlab,GLOW的Python增补。NCAR只想发布基本代码

    idl代码与Matlab 辉光 Global airglOW模型,可以从Fortran 2003编译器中独立且轻松地进行访问。 可选提供脚本语言,包括: Python≥3.6 Matlab的 GNU八度≥4.2 IDL ...glat , glon , Q , Echar , Nb

    pcloud2grid:此函数将点云转换为 MATLAB 样式的网格。-matlab开发

    接收 xyz 格式的点云,然后将其转换为具有纬度向量、经度向量、glat/glon 网格(使用 meshgrid)和 az(高度)矩阵的 MATLAB 样式的网格。 然后将这些保存到指定的输出 .mat 文件中。

    MilkMan:银河计划数据缩减工具

    它的构建允许任何人检查志愿者为数据库中或任何 GLON、GLAT 位置的任何主题(图像)创建的分类。 对于每个图像,您都可以看到原始志愿者绘图、聚类结果和该地区 SIMBAD 上的对象(这一点还没有完全完成)。 例如...

    基于springboot开发的前后端分离的简易进销存后台管理系统.zip

    基于springboot的java毕业&课程设计

    基于springboot-mqtt的温度、湿度、六氟化硫浓度实时监控系统.zip

    基于springboot的java毕业&课程设计

    会计信息化对华强公司内部审计的影响研究.docx

    会计信息化对华强公司内部审计的影响研究.docx

    修改谷歌提供的样例量子卷积神经网络模型,基于KDD99数据集进行训练,实现了网络攻击分类检测。.zip

    卷积神经网络(Convolutional Neural Networks, CNNs 或 ConvNets)是一类深度神经网络,特别擅长处理图像相关的机器学习和深度学习任务。它们的名称来源于网络中使用了一种叫做卷积的数学运算。以下是卷积神经网络的一些关键组件和特性: 卷积层(Convolutional Layer): 卷积层是CNN的核心组件。它们通过一组可学习的滤波器(或称为卷积核、卷积器)在输入图像(或上一层的输出特征图)上滑动来工作。 滤波器和图像之间的卷积操作生成输出特征图,该特征图反映了滤波器所捕捉的局部图像特性(如边缘、角点等)。 通过使用多个滤波器,卷积层可以提取输入图像中的多种特征。 激活函数(Activation Function): 在卷积操作之后,通常会应用一个激活函数(如ReLU、Sigmoid或tanh)来增加网络的非线性。 池化层(Pooling Layer): 池化层通常位于卷积层之后,用于降低特征图的维度(空间尺寸),减少计算量和参数数量,同时保持特征的空间层次结构。 常见的池化操作包括最大池化(Max Pooling)和平均池化(Average Pooling)。 全连接层(Fully Connected Layer): 在CNN的末端,通常会有几层全连接层(也称为密集层或线性层)。这些层中的每个神经元都与前一层的所有神经元连接。 全连接层通常用于对提取的特征进行分类或回归。 训练过程: CNN的训练过程与其他深度学习模型类似,通过反向传播算法和梯度下降(或其变种)来优化网络参数(如滤波器权重和偏置)。 训练数据通常被分为多个批次(mini-batches),并在每个批次上迭代更新网络参数。 应用: CNN在计算机视觉领域有着广泛的应用,包括图像分类、目标检测、图像分割、人脸识别等。 它们也已被扩展到处理其他类型的数据,如文本(通过卷积一维序列)和音频(通过卷积时间序列)。 随着深度学习技术的发展,卷积神经网络的结构和设计也在不断演变,出现了许多新的变体和改进,如残差网络(ResNet)、深度卷积生成对抗网络(DCGAN)等。

    用泽尼克多项式拟合表面的功能matlab代码.zip

    1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    毕业设计基于java+Springboot+协同过滤的新闻推荐系统源码+全部资料(高分项目).zip

    毕业设计基于java+Springboot+协同过滤的新闻推荐系统源码+全部资料(高分项目本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 【备注】 1、该项目是个人高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。毕业设计基于java+Springboot+协同过滤的新闻推荐系统源码+全部资料(高分项目毕业设计基于java+Springboot+协同过滤的新闻推荐系统源码+全部资料(高分项目毕业设计基于java+Springboot+协同过滤的新闻推荐系统源码+全部资

    基于vue可视化前段开发的拖拽编辑,页面生成工具.zip

    基于vue可视化前段开发的拖拽编辑,页面生成工具.zip

    HLC直播视频流播放器

    HLC直播视频播放器示例代码,代码2021年的时候因工作需要实现,参考网上资源采用了jquery等框架。

    基于卷积循环神经网络的数字识别.zip

    基于卷积循环神经网络的数字识别

    课设毕设基于SpringBoot+Vue的家具销售电商平台 LW+PPT+源码可运行.zip

    课设毕设基于SpringBoot+Vue的家具销售电商平台 LW+PPT+源码可运行.zip

    2007开关稳压电源(E题).doc

    包含作品的设计论文doc文档,可直接修改,适合于电赛备赛、课程设计、毕设参考等。 摘 要 该电源以单端反激式DC-DC变换器为核心。市电通过自耦式调压器,隔离变压器,整流滤波后产生直流电压,经DC-DC变换得到题目所需输出电压,实现了开关稳压电源的设计。DC-DC变换器采用脉宽调制器(PWM)UC3842,通过调节占空因数使得输出电压UO在30V~36V范围内可调;微控制器与键盘显示构成了控制显示模块,能对输出电压进行键盘设定和步进调整,并显示输出电压、电流的测量和数字显示功能,形成了良好的人机界面。 关键词:DC-DC变换器,脉宽调制器(PWM)

    520节日画图代码.zip

    520是每年的5月20日,因数字“520”与“我爱你”发音相似而被许多年轻人用作表达爱意的节日。这个节日起源于中国互联网文化,逐渐传递到其他国家和地区。在这一天,情侣们通常会互送礼物、发表情、或者举行浪漫的活动来庆祝爱情。快来领取专属于程序员的浪漫吧!表白的套路很多,但都少不了送花送礼物,作为一个程序员,搞不懂现在流行的泡泡机、小猪、重力感应车等玩具,也不想去让朋友们去送钱炫耀,毕竟真情才重要,钱就物质了。我能给各位单身粉丝们做的可能就只有分享几个表白代码了,在电脑上敲上几行代码,让她在郁闷的周一得到一个大大的惊喜,很简单,一看就会,如果现在用不到也不要紧,先收藏起来,反正这样的节日很多,以后用的时候能找到。

    带你学AI基于PP-OCR和ErnieBot的字幕提取和智能视频问答

    本次分享将带领大家从 0 到 1 完成一个基于 OCR 和 LLM 的视频字幕提取和智能视频问答项目,通过 OCR 实现视频字幕提取,采用 ErnieBot 完成对视频字幕内容的理解,并回答相关问题,最后采用 Gradio 搭建应用。本项目旨在帮助初学者快速搭建入门级 AI 应用,并分享开发过程中遇到的一些坑,希望对感兴趣的同学提供一点帮助。 参考https://blog.csdn.net/u010522887/article/details/139025542,跟随笔者共同走完一个完整的视频问答项目,从基础的动手跑通 CRNN 文本识别任务,再到应用开发和部署,旨在帮助初学者快速入门 OCR 相关技术并搭建一个简单的应用。 资源包包括前端文档中提到的源码和示例视频。 本系列的后续文章将沿袭这一思路,继续分享更多采用 Paddle 深度学习框架服务更多产业应用的案例。如果对你有帮助,欢迎 **关注 收藏** 支持

    毕设设计-学生宿舍管理系统 基于SpringBoot实现,界面简洁,功能完善

    毕设设计-学生宿舍管理系统 基于SpringBoot实现,界面简洁,功能完善 主要功能 ● 定位打卡、宿舍智能分配、学生信息管理、资讯管理(权限设计)等 使用 ● mysql、git、springboot ● 数据库初始化sql存储在doc文件夹下面 设计一个基于Spring Boot的学生宿舍管理系统,你需要确保系统既满足实用性,又保证界面简洁、功能完善。以下是一个基本的设计方案,包括系统的功能模块、技术栈选择和界面设计要点。 ### 功能模块 1. **用户认证模块**: - 登录/登出功能。 - 用户权限管理(如学生、宿舍管理员、系统管理员)。 2. **学生信息管理**: - 学生基本信息录入、查询、修改和删除。 - 宿舍分配与调换。 3. **宿舍楼管理**: - 宿舍楼信息维护。 - 宿舍房间信息管理。 4. **维修报修管理**: - 学生报修申请。 - 维修状态跟踪。 5. **来访登记管理**: - 来访人员登记。 - 访问记录查询。 6. **公告与通知发布**: - 发布宿舍相关公告和通知。

    源码小游戏微信飞机大战

    源码小游戏微信飞机大战

    一个前后端分离的仿知乎问答论坛.zip

    基于springboot的java毕业&课程设计

Global site tag (gtag.js) - Google Analytics