剑指offer - 44.数字序列中的某一位的数字***(需重做)

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

思路:
(自己想的思路,但不熟练,后面参考了点书上,要重做)
先手动模拟,对于13,前面有10个1位数的,所以13-10=3,代表从10开始的两位数中的第3位,写出来是101112…,那么从0开始计第3个为1(为什么从0开始,因为10-10=0,第10位就是现在的第0位)。如果用公式来算,位数为2,2位一组,3/2=1…1(商为1余1),商表示从10开始的多少个数,1那么就是10开始的第1个数(从0计),对应真实值10+1=11,余数为1表示第1位(从0计),最后的1.

再模拟一下1001,先确定是处在几位数的组合上,因为1位对应0~ 9(共占10位),2位对应10 ~99(共占9* 10* 2位,9表示十位1 ~9,10表示个位0 ~9,2表示每个数字占2位),3位对应100 ~ 999(共占9* 100* 3位,同理),4位…同样,直到找到选x位比1001小,但选x+1位比1001大。 可以发现10+180<1001,但10+180+2700>1001,所以它处在第3位的组合上。(通过while循环解决)
1001-(10+180)=811,811/3=270…1,商270表示从100开始第270个位置,所以真实值为270+100=370,余数1表示第1位,对应7。(余数0则表示第0位,对应3. 可以通过整除和取余操作)

代码:

#include <iostream>
#include <vector>  
#include<algorithm>
using namespace std;

int getNPosition(int n) {
	int num = 1; //表示应该出现在几位数里面,3表示在100~999中。
	if (n < 0) return -1;
	else if (n <= 9) return n;
	else if (n > 9) {
		int sum1 = 10;
		while (n>= sum1)
		{
			n -= sum1;
			num += 1;
			sum1 = (num*int(pow(10, num - 1))) * 9;
		}
	}
	int shang = n / num;
	int yu = n % num;
	int tmp = int(pow(10, num - 1)) + shang;
	tmp = tmp / int(pow(10, (num - yu - 1)));//右移(num - yu - 1)位
	tmp = tmp % 10;
	return tmp;
}

int main()
{
	int input[] = { 0,1,5,10,13,19,190,1001 };
	int res;
	for (int n : input) {
		res = getNPosition(n);
		cout << n <<"==>"<< res << endl;
	}
	return 0;
}

在这里插入图片描述

others:上次有个北邮的哥们 把我刺激到了,电子信息专业的,一起和我们面试,他说已经刷了800多道题了,将近1年,而且leetcode上都是自己写出来的,半小时想思路,做不出来再看答案。当时见他时微软已经4面过了,他们只考算法题,他都做出来了,我估计能拿到offer。
不刷题是不行的,不仅仅是找工作时要刷,算法能力更是一种能力的体现吧,而且可以直接考察基本功,所以要重视。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值