由于这道题目在牛客上没有,所以在此记录一下。

一.题目大意:

数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数,即从第0位开始)是5,第13位是1,第19位是4,等等。请写一个函数,求任意第n位对应的数字。

二.题解
《剑指offer》上提供了两种思路。

方法1:

第一种思路是:从0开始枚举每个数字。每枚举一个数字的时候,求出该数字是几位(如15是2位数、9323是4位数),并把该数字的位数和前面所有数字的位数累加。如果位数之和仍然小于等于n,则继续枚举下一个数字。当累加的数位大于n时,那么第n位数字一定在这个数字里。(此处为什么是大于而不是大于等于?因为是从0开始计数的,实质应为第n+1位)该算法的时间复杂度为O(N),当N很大时(如N = 10 ^ 11)往往会超时。

方法2;

这种方法是本文论述的重点,其实本提可以采用和文章http://www.cnblogs.com/wangkundentisy/p/8920147.html中的第二题的方法4类似。我们令f(m)表示"从0~长度为m的最大的数字"的数字个数之和,由此我们可以继续分析:

f(0) = 0

f(1) =10 + 0 = 10 (对应0 ~ 9)

f(2) =90 * 2 + f(1) = 190 (对应10 ~99, 0 ~ 9)

f(3) =900 * 3 + f(2) = 2890 (对应100 - 999,0 ~ 99)

f(4) = 9000 * 4 + f(3) =38890 (对应1000 ~ 9999,0 ~ 999)

....

f(m) = 9 * 10^(i - 1) * m + f(m-1)

其中m表示数字的长度。求出f(m)之后,剩下的就比较好解了。

对于数字n,我们只需要比较n与数组f中每个元素,如果f(k) >= n,其中k是满足前面条件的最小值,那么我们就可以确定最终的数字长度一定是k了。所以令n = n - f(k - 1),然后根据n / k和n % k的结果,就能知道最终的数字R和R中的哪个位置。

举个例子:

假设 n = 1001,由于f(2) < 1001且f(3) > 1001,所以最终的数字一定是3位数的数字。令n = n - f(2) = 811。有811 / 3 =270  ,811 % 3 = 1。所以最终的数字为100 + 270 = 370,且是370中的第1位数(从0开始计数),所以最终的结果是7。

具体代码如下:

#include<iostream>
#include<unordered_map>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<sstream>
using namespace std;
#define max_len 9
int TheNthDigit(long long f[],int n)
{
if(n < 0)
return -1;
if(n <= 9)
return n;
int pos = 0;
for(int i = 1; i <= max_len ;i++)
if(f[i] >= n)
{
pos = i;
break;
}
n = n - f[pos - 1];
int temp1 = n / pos;
int temp2 = n % pos;
int temp3 = temp1 + pow(10, pos - 1);
return (int)(temp3 / pow(10,pos - temp2 -1)) % 10; }
int main()
{
long long f[] = {0,10,190,2890,38890,488890,5888890,68888890,788888890,8888888890};//初始化长度数组
int n;
cin >> n;
cout<<TheNthDigit(f,n)<<endl;
}

该算法的时间复杂度为常数级,并且此处的代码支持的数字最大长度为9,即 N = 999999999。当然你可以任意调整,但数组f也需要相应的调整。

有几点需要注意:

1.当n <= 9时,这个通用的公式就不支持了,需要单独处理。

2.此处同http://www.cnblogs.com/wangkundentisy/p/8920147.html一样,我是事先算出的数组f的各个值。当然也可以在代码中迭代计算,但是我不建议这么做。因为要利用的pow函数,而pow函数的返回值是double类型,它在其强制转换成整型或长整型的过程中,有可能会有误差,最终导致计算结果不准确。所以我建议最好是事先算出来数组f的各个元素,况且f中的元素并不难计算,都是有规律的。

3.还有需要注意的一点是数组f一定是long long型的,否则当数据比较大的时候,就不支持了。

数字序列中某一位数字(《剑指offer》面试题44)的更多相关文章

  1. 剑指 Offer 44. 数字序列中某一位的数字 + 找规律 + 数位

    剑指 Offer 44. 数字序列中某一位的数字 Offer_44 题目描述 题解分析 java代码 package com.walegarrett.offer; /** * @Author Wale ...

  2. 《剑指offer》第四十四题(数字序列中某一位的数字)

    // 面试题44:数字序列中某一位的数字 // 题目:数字以0123456789101112131415…的格式序列化到一个字符序列中.在这 // 个序列中,第5位(从0开始计数)是5,第13位是1, ...

  3. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

  4. C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解

    剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...

  5. C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解

    剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...

  6. C++版 - 剑指offer 面试题22:栈的压入、弹出序列 题解

    剑指offer 面试题22:栈的压入.弹出序列 提交网址: http://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId ...

  7. 剑指offer面试题:输入某二叉树的前序遍历和中序遍历,输出后序遍历

    二叉树的先序,中序,后序如何遍历,不在此多说了.直接看题目描述吧(题目摘自九度oj剑指offer面试题6): 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结 ...

  8. 【剑指Offer面试题】九度OJ1384:二维数组中的查找

    下决心AC全部剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> ...

  9. 剑指offer面试题3 二维数组中的查找(c)

    剑指offer面试题三:

随机推荐

  1. C++数组初始化

    局部数组:没有默认值,如果声明的时候不定义,则会出现随机数(undefined): 全局数组:声明时不赋值,默认值为0

  2. ace编辑器 光标错位

    字体的关系

  3. Unity等待写入数据

    EasyTouch中QuickGesture的用法 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Qu ...

  4. 改变radio单选按钮的样式

    <div class="choose_btn"> <input type="radio" name="choose_raido&qu ...

  5. (20)jQuery的文档操作(创建,添加、设置样式和删除等)

    <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>jq ...

  6. Redis 开发与运维

    Getting Start 高性能 性能优势的体现 C语言实现的内存管理 epoll的I/O多路复用技术+IO连接/关闭/读写通过事件实现异步的非阻塞IO TCP协议 单线程架构,不会因为高并发对服务 ...

  7. 比较器(TreeSet和优先队列,可以对里面的元素按照自己的意愿进行排序)

    class MyComparator implements Comparator<Integer>{ public int compare(Integer o1, Integer o2) ...

  8. 每天进步一点点- 资源与URI(吐血精华总结)

    1.资源(Resources) 每一个URI代表一种资源这句话的理解 ***************************************************************** ...

  9. terraform 几个方便的工具

    几个方便的terraform 工具,方便了解terraform terraform-docs 方便的查看资源的信息(支持markdown,json 格式),对于ci/cd 很方便 项目地址 https ...

  10. buckaroo 试用

    我系统是mac 所以选择的是mac 的版本,官方是支持跨平台的. 安装 mac 版本安装 wget https://github.com/LoopPerfect/buckaroo/releases/d ...