跟着姚桑学算法-数字序列中某一位的数字

简介: 剑指offer算法

题. 数字序列中某一位的数字

数字以 0123456789101112131415… 的格式序列化到一个字符序列中。

在这个序列中,第 5 位(从 0 开始计数)是 5,第 13 位是 1,第 19 位是 4,等等。

请写一个函数求任意位对应的数字。

数据范围
0≤ 输入数字 ≤2147483647

样例

输入:13

输出:1

【题解】--- 模拟

模拟一个实例,n = 1022,匹配到的数是377,对应它的第2位,也就是3后面的那个7,输出ans是7。

  1. 首先不断地对1022进行处理,也就是第1个while()循环做的事情,得到base = 100, i = 3, n = 833。那么得到的信息就是1022位数处于3位数的区间,那一位从100开始数,是第833位。
  2. 第二步,我们就可以通过100和3和833这三个信息推出1022位数字,具体落脚在了哪个3位数上。
  3. 我们来逆推下公式,比如377这个数,(377−100+1)∗3(377−100+1)∗3得到的就是100到377有多少位数字,结果是834。
  4. 我们上面求出的n是833,834指的是377最后一位的位数。所以为了求出377,我们通过(n + (i - 1)) / i,从而求出来它具体在第几位。然后得出在100后面的第278位,最后(278 + 100 - 1) = 377。
  5. 得到number后,我们通过 833 % i的结果,如果能除尽,就是number的最后一位,也就是i位;不然就是number中从第1位算起的第n % i位(下标从1开始哦)。
  6. 算出来r是2后,说明是377的第2位,也就是第1个7,我们让它除10,一次,除10的次数是[0 ~ i - r)
  7. 处理后的number的个位就是要求的答案,我们返回的时候number %10就ok。

复杂度分析:

1. 确定寻找的n处于几位数的范畴,1位数,2位数,还是3位数....这里的时度是O(1)。
2. 确定是i位数后,确定是i位数中的哪个,比如说4位数的第256个数,1000 + 256 - 1 = 1255,1255就是4位数的其中1个。
这里的时度是O(1),用到了除法。
3. 确定是哪个数以后(比如确定是1255这个数以后),看看数字n是这个数的第几位,拿1255来举例子,是1还是2还是5还是5。
这里是取余,时度是O(1)的,然后取出来是哪一位数,最多是10位,所以最多是10次操作,时间复杂度为O(log10n)。

C++代码实现:

class Solution {
public:
    int pow10(int x){
        int res=1;
        for(int i=0;i<x;i++){
            res*=10;
        }
        return res;
    }
    int digitAtIndex(int n) {
        if(n<10){
            return n;
        }

        int m=n-9;
        long long k=2;
        while(m>9*k*pow10(k-1)){
            m-=9*k*pow10(k-1);
            k++;
        }
        //t---第t个k位数
        int t=m/k;
        int s=m%k;
        int num=pow10(k-1);
        num+=t;
        if(s==0){
            return (num-1)%10;
        }
        else{
            for(int i=0;i<k-s;i++){
                num/=10;
            }
            return num%10;
        }
    }
};
目录
相关文章
|
2月前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
76 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
3月前
|
算法 数据可视化
基于SSA奇异谱分析算法的时间序列趋势线提取matlab仿真
奇异谱分析(SSA)是一种基于奇异值分解(SVD)和轨迹矩阵的非线性、非参数时间序列分析方法,适用于提取趋势、周期性和噪声成分。本项目使用MATLAB 2022a版本实现从强干扰序列中提取趋势线,并通过可视化展示了原时间序列与提取的趋势分量。代码实现了滑动窗口下的奇异值分解和分组重构,适用于非线性和非平稳时间序列分析。此方法在气候变化、金融市场和生物医学信号处理等领域有广泛应用。
160 19
|
3月前
|
算法 数据可视化 数据安全/隐私保护
基于LK光流提取算法的图像序列晃动程度计算matlab仿真
该算法基于Lucas-Kanade光流方法,用于计算图像序列的晃动程度。通过计算相邻帧间的光流场并定义晃动程度指标(如RMS),可量化图像晃动。此版本适用于Matlab 2022a,提供详细中文注释与操作视频。完整代码无水印。
|
4月前
|
机器学习/深度学习 数据采集 算法
【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现
本文介绍了一个基于Python的时间序列模型,用于分析和预测2021-2022年重庆地区的气温变化趋势,通过ARIMA和LSTM模型的应用,揭示了气温的季节性和趋势性变化,并提供了对未来气温变化的预测,有助于气象预报和相关决策制定。
111 1
【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现
|
5月前
|
自然语言处理 算法 搜索推荐
字符串相似度算法完全指南:编辑、令牌与序列三类算法的全面解析与深入分析
在自然语言处理领域,人们经常需要比较字符串,这些字符串可能是单词、句子、段落甚至是整个文档。如何快速判断两个单词或句子是否相似,或者相似度是好还是差。这类似于我们使用手机打错一个词,但手机会建议正确的词来修正它,那么这种如何判断字符串相似度呢?本文将详细介绍这个问题。
296 1
|
4月前
|
算法
【算法】栈算法——栈的压入、弹出序列
【算法】栈算法——栈的压入、弹出序列
|
4月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
43 0
|
5月前
|
机器学习/深度学习 数据采集 算法
Python实现Prophet时间序列数据建模与异常值检测(Prophet算法)项目实战
Python实现Prophet时间序列数据建模与异常值检测(Prophet算法)项目实战
379 2
|
6月前
|
机器学习/深度学习 人工智能 算法
【机器学习】Q-Learning算法:在序列决策问题中的实践与探索
【机器学习】Q-Learning算法:在序列决策问题中的实践与探索
146 0
【机器学习】Q-Learning算法:在序列决策问题中的实践与探索
|
6月前
|
算法 Shell C语言
数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)
数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)
66 0