2023-05-01:给你一个整数 n ,

请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...]

中找出并返回第 n 位上的数字。

1 <= n <= 2^31 - 1。

输入:n = 11

输出:0

解释:第 11 位数字在序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 里是 0 ,它是 10 的一部分。

答案2023-05-01:

该程序的大体过程:

1.定义数组 under 和 help,分别用于存储数字位数对应能处理的数的个数和指示各位数之间的跨度。

2.实现函数 findNthDigit,其输入为整数 n,表示要查找的数字在整数序列中的位置。根据 under 数组,找到包含第 n 个数字的区间长度 len,并返回调用子函数 number 的结果。

3.实现函数 number,其输入为当前路径 path、数字的位数 len、最高位的权重 offset、最低位的权重 all 和从开始算起剩余的第几个数字 nth。如果 offset 等于 0,则说明已经到达最低位,直接返回路径经过的值中的第 nth 个数字;否则,计算出当前节点 cur 取值(这可能需要根据 offset 来进行特殊处理),根据 all 和 offset 计算下一个节点的路径 cur*(all/offset)+path,并递归地调用 number 函数。

4.在 main 函数中,定义一个整数变量 n 表示要查找的数字在整数序列中的位置,调用 findNthDigit 函数查找第 n 个数字,并输出结果。

时间复杂度和空间复杂度如下:

1.findNthDigit 函数中的循环需要遍历数组 under,时间复杂度为 O(1) 平均时间复杂度为 O(log n);

2. number 函数实现了一个递归结构,每次递归除去常数项的时间复杂度为 O(1), 递归深度为 O(log n),所以总时间复杂度为 O(log n);

3.数组 under 和 help 的空间复杂度分别为 O(1),而递归调用 number 函数时,栈空间的最大使用量也为 O(log n)。因此,总的空间复杂度为 O(log n)。

综上所述,该算法的时间复杂度和空间复杂度均为 O(log n)。

go完整代码如下:

package main

var under = []int64{
0, 9, 189, 2889, 38889, 488889, 5888889, 68888889, 788888889, 8888888889, 98888888889,
} var help = []int{
0,
1, // 1
10, // 2
100, // 3
1000, // 4
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
} func findNthDigit(n int) int {
l := 0
for i := 1; i < len(under); i++ {
if under[i] >= int64(n) {
l = i
break
}
}
return number(0, l, help[l], help[l], n-int(under[l-1]))
} // path : 路径 左(低) <- 右(高)
// len : n -> 5位数 len = 5 固定!
// offset : 10000 目前要决定的是高1位
// 1000 目前要决定的是高2位
// 10 目前要决定的是高2位
// 可变
// all : 10000 固定
// nth : 第几个
func number(path, len, offset, all, nth int) int {
if offset == 0 {
return (path / help[nth]) % 10
} else {
j := (nth - 1) / (len * offset)
cur := 0
if offset == all {
cur = 1
}
cur += j
return number(cur*(all/offset)+path, len, offset/10, all, nth-j*len*offset)
}
} func main() {
n := 11
digit := findNthDigit(n)
println(n, "th digit is", digit)
}

rust完整代码如下:

static mut UNDER: [i64; 11] = [
0,
9,
189,
2889,
38889,
488889,
5888889,
68888889,
788888889,
8888888889,
98888888889,
];
static mut HELP: [i32; 11] = [
0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
]; fn find_nth_digit(n: i32) -> i32 {
let under: &[i64; 11];
let help: &[i32; 11];
unsafe {
under = &UNDER;
help = &HELP;
} let mut len = 0;
for i in 1..under.len() {
if under[i] >= n as i64 {
len = i;
break;
}
} number(0, len, help[len], help[len], (n - under[len - 1] as i32))
} // path : 路径 左(低) <- 右(高)
// len : n -> 5位数 len = 5 固定!
// offset : 10000 目前要决定的是高1位
// 1000 目前要决定的是高2位
// 10 目前要决定的是高2位
// 可变
// all : 10000 固定
// nth : 第几个
fn number(path: i32, len: usize, offset: i32, all: i32, nth: i32) -> i32 {
let help: &[i32; 11];
unsafe {
help = &HELP;
} if offset == 0 {
return (path / help[nth as usize]) % 10;
} else {
let j = (nth - 1) / (len as i32 * offset);
let cur = if offset == all { 1 } else { 0 } + j;
return number(
cur * (all / offset) + path,
len,
offset / 10,
all,
nth - j * len as i32 * offset,
);
}
} fn main() {
unsafe {
let n = 11;
let digit = find_nth_digit(n);
println!("{}th digit is {}", n, digit);
}
}

c完整代码如下:

#include <stdio.h>

const long under[] = {
0L, // 0位数,一共能解决几个位
9L, // 1位数,一共能解决几个位
189L, // 1~2位数,一共能解决几个位
2889L, // 1~3位数,一共能解决几个位
38889L,
488889L,
5888889L,
68888889L,
788888889L,
8888888889L,
98888888889L
}; const int help[] = {
0,
1, // 1
10, // 2
100, // 3
1000, // 4
10000,
100000,
1000000,
10000000,
100000000,
1000000000
}; int findNthDigit(int n) {
int len = 0;
for (int i = 1; i < sizeof(under) / sizeof(long); i++) {
if (under[i] >= n) {
len = i;
break;
}
}
return number(0, len, help[len], help[len], n - under[len - 1]);
} // path : 路径 左(低) <- 右(高)
// len : n -> 5位数 len = 5 固定!
// offset : 10000 目前要决定的是高1位
// 1000 目前要决定的是高2位
// 10 目前要决定的是高2位
// 可变
// all : 10000 固定
// nth : 第几个
int number(int path, int len, int offset, int all, int nth) {
if (offset == 0) {
return (path / help[nth]) % 10;
}
else {
int j = (nth - 1) / (len * offset);
int cur = (offset == all ? 1 : 0) + j;
return number(cur * (all / offset) + path, len, offset / 10, all, nth - j * len * offset);
}
} int main() {
int n = 11;
int digit = findNthDigit(n);
printf("%dth digit is %d\n", n, digit);
return 0;
}

c++完整代码如下:

#include <iostream>
using namespace std; const long under[] = {
0L, // 0位数,一共能解决几个位
9L, // 1位数,一共能解决几个位
189L, // 1~2位数,一共能解决几个位
2889L, // 1~3位数,一共能解决几个位
38889L,
488889L,
5888889L,
68888889L,
788888889L,
8888888889L,
98888888889L
}; const int help[] = {
0,
1, // 1
10, // 2
100, // 3
1000, // 4
10000,
100000,
1000000,
10000000,
100000000,
1000000000
}; // path : 路径 左(低) <- 右(高)
// len : n -> 5位数 len = 5 固定!
// offset : 10000 目前要决定的是高1位
// 1000 目前要决定的是高2位
// 10 目前要决定的是高2位
// 可变
// all : 10000 固定
// nth : 第几个
int number(int path, int len, int offset, int all, int nth) {
if (offset == 0) {
return (path / help[nth]) % 10;
}
else {
int j = (nth - 1) / (len * offset);
int cur = (offset == all ? 1 : 0) + j;
return number(cur * (all / offset) + path, len, offset / 10, all, nth - j * len * offset);
}
} int findNthDigit(int n) {
int len = 0;
for (int i = 1; i < sizeof(under) / sizeof(long); i++) {
if (under[i] >= n) {
len = i;
break;
}
}
return number(0, len, help[len], help[len], n - under[len - 1]);
} int main() {
int n = 11;
int digit = findNthDigit(n);
cout << n << "th digit is " << digit << endl;
return 0;
}

2023-05-01:给你一个整数 n , 请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n 位上的数字。 1 <= n <=的更多相关文章

  1. 刷题之给定一个整数数组 nums 和一个目标值 taget,请你在该数组中找出和为目标值的那 两个 整数

    今天下午,看了一会github,想刷个题呢,就翻出来了刷点题提高自己的实际中的解决问题的能力,在面试的过程中,我们发现,其实很多时候,面试官 给我们的题,其实也是有一定的随机性的,所以我们要多刷更多的 ...

  2. 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。

    /** * 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标. * * 你可以假设每种输入只会对应一个答案.但是,数组中 ...

  3. 用C#写一个函数,在一个数组中找出随意几个值相加等于一个值 与迭代器对比

    算法!用C#写一个函数,在一个数组中找出随意几个值相加等于一个值比如,数组{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}  要找出那些数相加等 ...

  4. C语言:从p所指字符串中找出ASCII码最大的字符,将其放在第一个位置上,并将该字符前的原字符向后顺序移动。-使字符串的前导*号不得多于n个,若多余n个,则删除多余的*号,

    //fun函数:从p所指字符串中找出ASCII码最大的字符,将其放在第一个位置上,并将该字符前的原字符向后顺序移动. #include <stdio.h> void fun( char * ...

  5. 怎样计算一个整数的位数&并把每一位上的数字保存下来

    用循环来解决~~ M每次除以10, 再用一个变量count来计数,每循环一次 加1,直到这个数除去10后的数小于10 ,count再加1就可以了 实例:整数M=4325, 第一次:4325/10=43 ...

  6. 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

    class Solution {     public int[] twoSum(int[] nums, int target) {         for (int i = 0; i < nu ...

  7. 记录:50多行程序中找出多写的一个字母e

    小霍同学调程序,做的是第11周的项目1 - 存储班长信息的学生类,可是她写的程序(就在以下),呃,请读者自己执行一下吧.(下午在机房调试时用的是Code::Blocks10.05.输出的是非常长的莫名 ...

  8. 采用BitMap从20亿个int正整数中找出相同的数字

    所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来存储数据,因此可以大大节省存储空间. public class Test { ...

  9. HJ92 在字符串中找出连续最长的数字串

    描述 输入一个字符串,返回其最长的数字子串,以及其长度.若有多个最长的数字子串,则将它们全部输出(按原字符串的相对位置) 本题含有多组样例输入. 输入描述: 输入一个字符串. 输出描述: 输出字符串中 ...

  10. oracle中找出某个字段中有非数字型的记录

    工作中遇到一个大表记录中有非法非数字字符,不想用正则语法去做, 用一条SQL语句查出来的方法如下: select * from table where translate(col,'*01234567 ...

随机推荐

  1. 转载C#加密方法

    方法一:    //须添加对System.Web的引用     using System.Web.Security;          ...          /// <summary> ...

  2. 3DMAX2018安装

    1.下载3DMAX2018安装包并解压 2.打开解压后的文件点击Setup 选择语言和安装位置点击下一步 安装完成后点击enter a serial number 输入序列号066-66666666, ...

  3. 使用ActiveMQ中遇到的端口占用问题

    原Linux虚拟机中安装了ActiveMQ,EMQX.后期使用中主要使用EMQX来实现消息服务,停止了ActiveMQ.但是虚拟机挂起之后,长时间未再使用.近期由于有使用ActiveMQ的需要,而临时 ...

  4. GO语言学习笔记-方法篇 Study for Go ! Chapter five - Method

    持续更新 Go 语言学习进度中 ...... GO语言学习笔记-类型篇 Study for Go! Chapter one - Type - slowlydance2me - 博客园 (cnblogs ...

  5. C#比较类/接口、Dictionary 排序

    作者:l625208058 链接:https://www.jianshu.com/p/cd1be6652570 先 F12 看下 List.Sort() 方法 public void Sort(int ...

  6. Solon Initializr v1.2 发布

    Solon Initializr 是 Solon 框架的模板生成器项目.本期更新增加了快捷组合包的依赖选择,并生成对应的项目模板. 更新说明 增加 Solon Lib 依赖选择,并生成对应项目 增加 ...

  7. [C++STL教程]7.priority_queue优先队列入门学习!零基础都能听懂的教程

    不知不觉C++STL教程系列已经第7期了.之前我们介绍过:vector, queue, stack, set, map等等数据结构. 今天我们来学习一个新的stl容器:priority_queue优先 ...

  8. 【故障公告】数据库服务器 CPU 近 100% 造成全站故障,雪上加霜难上加难的三月

    数据库服务器 CPU 近 100% 问题几乎每年都要发生一次,上次发生在去年1月31日,每次都是通过主备切换或者重启实例解决,数据库服务用的是阿里云 RDS SQL Server 2016 标准版. ...

  9. ArgoCD实践之基于配置清单创建Application

    1. 什么是Application ArgoCD的两个核心概念为Application和Project,他们可分别基于Application CRD和AppProject CRD创建; 核心组件: A ...

  10. 【Visual Leak Detector】配置项 ForceIncludeModulesmd

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记.本篇介绍 VLD 配置文件中配置项 ForceIncludeModules 的使用方法. 同系列文章目录可见 <内存泄漏检测工具&g ...