剑指offer:数字序列中某一位的数字

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

# -*- coding: utf-8 -*-
# @Time         : 2019-07-09 22:51
# @Author       : Jayce Wong
# @ProjectName  : job
# @FileName     : digitAtIndex.py
# @Blog         : https://blog.51cto.com/jayce1111
# @Github       : https://github.com/SysuJayce

def countOfDigit(digit):
    return 9 * 10 ** (digit - 1) if digit > 1 else 10

def findDigitWithinRange(digit, index):
    if digit == 1:
        number = 0
    else:
        number = 10 ** (digit - 1)
    number += index // digit
    remainder = index % digit
    return str(number)[remainder]

def digitAtIndex(index):
    """
    最直观的做法就是从0开始遍历所有整数,然后统计已经出现了多少位数字,直到直到所求下标的数字。这样
    做的话效率太低。

    如果我们能先确定所求下标的数字是属于几位小数的,即先确定答案位于三位数还是四位数还是五位数的数
    字中,然后再在这个位数段中确定具体是哪个数字,最后在这个数字中确定是哪一位,这样就可以大大降低
    复杂度。
    """
    if index < 0:
        return -1
    # 所求的位置属于几位数,先从个位开始
    digit = 1
    while True:
        # 如果确定了所求位置属于几位数了,就进一步求具体的数字
        if index <= countOfDigit(digit):
            return findDigitWithinRange(digit, index)
        # 否则跳过这个n位数
        index -= countOfDigit(digit) * digit
        digit += 1

def main():
    print(digitAtIndex(21))

if __name__ == ‘__main__‘:
    main()

原文地址:https://blog.51cto.com/jayce1111/2419109

时间: 2024-10-08 19:11:28

剑指offer:数字序列中某一位的数字的相关文章

剑指Offer对答如流系列 - 数字序列中某一位的数字

面试题44:数字序列中某一位的数字 题目描述 数字以0123456789101112131415-的格式序列化到一个字符序列中.在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等.请写一个函数求任意位对应的数字. 问题分析 这个寻求高效的解决方法,也是寻找规律: 个位数的个数一共有10个,即0~9,共占了10*1位数字:(特殊) 两位数的个数一共有90个,即10~99,每个数字占两位,共占了90*2位数字: -- m位数的个数一共有9*10^(m-1)个,每个数字占m位,

《剑指offer》第四十四题:数字序列中某一位的数字

// 面试题44:数字序列中某一位的数字 // 题目:数字以0123456789101112131415…的格式序列化到一个字符序列中.在这 // 个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等.请写一 // 个函数求任意位对应的数字. #include <iostream> #include <algorithm> using namespace std; int countOfIntegers(int digits); int digitAtIndex(

剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)

题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 输入: 每个测试案例包括2行: 第一行输入一个整数n(1<=n<=100000),表示数组中元素的个数. 第二行输入n个整数,表示数组中的每个元素,这n个整数的范围是[1,1000000000]. 输出: 对应每个测试案例,输出出现的次数超过数组长度的一半的数,如果没有输出-1. 样例输入:

57. 数字序列中某一位的数字 (不懂)

算法1 以第15位数字1为例(1隶属与12,两位数,位于12从左侧以0号开始下标为0的位置)步骤1:首先确定该数字是属于几位数的;如果是一位数,n<9;如果是两位数,n<9+90X2=189;说明是两位数.因为是从0开始数数.0-9可以表示10个数字,从0开始数可以表示到9.10-99一共有90X2个数字,所以数到两位数能够数到9+90X2=189.步骤2:确定该数字属于哪个数.10+(15-10)/2= 12.步骤3:确定是该数中哪一位.15-10-(12-10)*2-1 = 0, 所以位于

【Java】 剑指offer(39) 数组中出现次数超过一半的数字

本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, 4, 2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 思路 思路一:数字次数超过一半,则说明:排序之后数组中间的数字一定就是所求的数字. 利用partition()函数获得某一随机数字,其余数字按大小排在该数字的左右.若该

《剑指offer》---数组中出现次数超过一半的数字

本文算法使用python3实现 1. 问题1 1.1 题目描述: ??数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在则输出0. ??时间限制:1s:空间限制:32768K 1.2 思路描述: ??方法一:新建一个字典,用来保存每次数字以及数字出现的次数,只不过这里考虑在每次对已存在的数字次数进行加一操作前,会先判断是否已满足条件,若已经满足条件

【剑指Offer】数组中出现次数超过一半的数字 Python版

题目描述 给定一个数组,如果这个数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字:如果不存在,则返回0. 思路分析 对于一个数组而言,满足题目要求的数字最多只有一个,可以采用数字相互抵消的思想.在遍历数组时,储存两个值now和count,now是当前数字,count是该数字的标记.当下一个数字与now相等时,标记count的值加1,如果不相等,则减1:当标记count的值变为0时,则将下一个数字的值用now来存储,并将count的值置为1,继续遍历完数组. 如果数组中存在出现次数超过

数字序列中某一位的数字

数字按照0123456789101112131415161718192021-的顺序排列.第5位(从0开始计数)为5,第13位为1,第19位为4-- 求任意第n位对应的数字. 思路: 直观方法做枚举.每枚举一个数字的时候,求出该数字是几位数,并把数字的位数和前面的所有数字的位数相加.当累加的数位大于n时,那么第n位数字一定在这个数字里. 以第15位数字2为例(2隶属与12,两位数,位于12从左侧以0号开始下标为1的位置) 步骤1:首先确定该数字是属于几位数的; 如果是一位数,n<9;如果是两位数

【剑指Offer】数组中出现次数超过一半的数字

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 算法描述 打擂算法:多的留下,少的走 先找出数最多的,然后找有多少个数,最后判断数目是否超过了一半, θ(n)时间复杂度 代码实现 class Solution { public: int MoreThanHalfNum_Solution(vector<int> numbers) { int v