题目:数字以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。
不刷题是不行的,不仅仅是找工作时要刷,算法能力更是一种能力的体现吧,而且可以直接考察基本功,所以要重视。