题目:
解法:
第一种:直接从1到n呗,
每个数字,我们从个位,十位,到最高位分析,有多少个就加上;
然后从1遍历到n,最后所有的加上,就是总数呗。
我们分析一下时间复杂度。每个数字的分析,肯定是lg(N)(肯定是以10为底,n的对数)
从1到n,那么时间复杂度就是nlogn
我没写,参考 https://blog.youkuaiyun.com/weixin_37672169/article/details/80950378
第二种,trick
作为一道分析数字规律的题目,我败了,但是查了好多博客,我感觉我参考的这种方法是最好的,为什么?
参考地址 :https://blog.youkuaiyun.com/littlehaes/article/details/92805867
/*
1,2,...n这n个数中
x位上每隔(x*10)个数出现x个1, n中有n/(x*10)个完整的(x*10),以百位为例,就是n中有n/1000个完整的1000, 分别是1~~1000,1001~~2000, 2001~~3000,...(n/1000 - 1)*1000 + 1~~(n/1000)*1000
最后还可能剩下不足1000的部分, 也就是从(n/1000)*1000+1~~n, 百位的情况对应n%1000
不足(x*10)的部分,也就是n%(x*10)的部分, x位上也有可能出现1
如果n%(x*10)<x, x位上没有1
如果n%(x*10)>2*x-1, x位上有x个1
如果n%(x*10)>=x && n%(x*10)<=2*x-1, x位上有n%(x*10) - x + 1个1
*/
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int count = 0;
for(int i=1; i<=n; i*=10){
count += n/(i*10) * i;
if(n%(i*10) > 2*i-1)
count += i;
else if(n%(i*10)>=i)
count += n%(i*10) - i + 1;
}
return count;
}
}