LeetCode400.第N个数字(C++实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28584889/article/details/84894950

题目描述

解题思路

这个题目猛一看没看懂啥意思。。

其实呢?他就是说m位的整数可以看做有m个数字,按照整数从小到大的顺序,求第n个数字是什么?

最简单想到的思路就是用字符串处理。把整数序列都存到字符串里面,那么小标为n-1的数字就是啦,但是明显这样会超时。

@@换一种思路->>>>>

发现这个是有一些数字规律的,那之后我们如何找到第n个数字是什么呢?

首先我们要知道第n个数字对应的整数是多少!!

下面以n = 56789为例,说明算法思想。

首先来一个循环,一位是数有9个,显然太少

2位数有180个,显然也太少

3位数有2700,还少

4位数有36000个,累计一下: 9+180+2700+36000 = 38889 还不够

5位数有5*90000= 450000;显然太多了!!!

所以,我们现在循环到4位数要截止,还剩下56789-38889=17900

也就是说还有17900个数字,我们前面四位数已经全部算完了,下面就只能上五位数了,从10000开始,17900/5=3580;也就是说剩下的17900个数字刚好够3580个五位整数分;从10000开始,到13579结束。刚好够分的意思就是到最后一个整数的最末位结束,那么结果就是13579的“9”了!!

那么,如果有余数呢?比如还剩17901个数字,而不是17900;那么17901够分3580个五位整数还余下一个数字;那这余下的一个数字就只能算到下一个整数了嘛。余数是多少,就意味着下一整数的哪一位数字。OK,就是这样了。

示例代码

//解法一
int findNthDigit(int n) {
	long long numbers = 0, tempNums;//numbers是累计的数字数目,tempNums是每一个循环所要加上的数字数目
	int answer;
	int digits = 1;//整数的位数
	while (numbers < n)
	{
		tempNums = (long long)9 * digits * (int)pow(10, digits - 1);
		numbers += tempNums;
		if(numbers >= n)
			break;
		digits++;
	}
	numbers -= tempNums;//循环跳出时,当前数目要减去上一轮循环的数字数目才ok
	answer = (int)pow(10, digits - 1) - 1 + (int)(n - numbers)/digits;
	//这个answer是暂时的,不是最终结果;
	if((n - numbers)%digits == 0)
		return answer%10;//如果剩余数字的数目对digits可以整除,说明所求答案就是最后一个数字的末尾数
	return ((answer + 1)/((int)pow(10, digits - (n - numbers)%digits)))%10;
	//如果不可以整除,说明所求答案是下一个整数,根据余数可以知道是哪一位!!
}

//解法二
int findNthDigit(int n) {
    long long digits = 1, temp = 0, base = 9;
    while (n > digits * base)
    {//n直接作为剩余的数字数目,当剩余数目小于某digits位的整数的所有数目时停止循环
        n -= (digits++) * base;
        temp += base;
        base *= 10;
    }//base就是digits-1位的整数的最大的那个
    if(n%digits == 0)//这里也是分情况,看余数是否等于0
        return to_string((int)(temp + n/digits))[digits - 1] - '0';
    else
        return to_string((int)(temp + n/digits + 1))[n%digits - 1] - '0';
}

解法二是解法一的变形,思路是完全一样的!!

猜你喜欢

转载自blog.csdn.net/qq_28584889/article/details/84894950
今日推荐