编程之美之1的数目

来源:互联网 发布:ubuntu安装deepin qq 编辑:程序博客网 时间:2024/04/28 11:07


 给定一个十进制正整数N,写下从1开始到N的所有整数,然后数一下其中1出现的次数。

例如:

N=2,写下1,2。1只出现了1次。

1、写一个函数f(N),返回1到N之间,出现的“1”的个数,比如f(12)=5;

2、满足条件“f(N)=N”的最大的N是多少?


解法一:

从1遍历到N,计算每个数[1...N]上出现的1的次数。

public class Main {public static void main(String[] args) {int n = 100000000;System.out.println(fun(n));}private static int fun(int n) {int count = 0;for (int i = 1; i <= n; i++) {count += funExtra(i);}return count;}private static int funExtra(int n) {int count = 0;while (n > 0) {count += (n % 10 == 1) ? 1 : 0;n /= 10;}return count;}}

解法一的时间复杂度为O(N*log2(N))。

解法二:

从个位到遍历到最高位,计算每个位上面1出现的次数,同时进行累加。

例如:

N=12013

1、在个位上为3,则“1”出现的次数与前面的4位“1201”有关,出现“1”的次数为1201+1=1202次;

2、在十位上位1,则“1”出现的次数与前面的3位“121”和后面的“3”有关,出现“1”的次数为120*10+(3+1)=1204次;

3、在百位上位0,则“1”出现的次数与前面的2位“12”和后面的“13”有关,出现“1”的次数为12*100=1200次;

4、在千位上位2,则“1”出现的次数与前面的1位“1”和后面的“13”有关,出现“1”的次数为(1+1)*1000=2000次;

4、在万位上位1,则“1”出现的次数与后面的“2013”有关,出现“1”的次数为2013+1=2014次;

一共有7620个1。

其中,要注意的是必须对每个位上出现的数字分三种情况进行讨论:

1、“0”,

2、“1”,

3、“2,3,4,5,6,7,8,9”

代码如下:

public class Main {public static void main(String[] args) {int n = 12013;System.out.println(fun(n));}private static int fun(int n) {int mCurrent = 0;int mUp = 0;int mDown = 0;int j = 1;int count = 0;while (n / j != 0) {mCurrent = n / j % 10;mUp = n / (10 * j);mDown = n - (n / j) * j;switch (mCurrent) {case 0:count += mUp * j;break;case 1:count += mUp * j + mDown + 1;break;default:count += (mUp + 1) * j;break;}j *= 10;System.out.println(count);}return count;}}


对于满足N=f(N)的最大N是多少。

我们如下分析:

当N<=9时,1有1个;

当N<=99时,1有20个;

当N<=999时,1有300个;

可以得出公式:f(10^n-1)=n*10^(n-1)

可以发现当n>=10时,f(10^n-1)<n*10^(n-1),当n<=9时,f(10^n-1)>n*10^(n-1)。

在10^9-1<N<10^10-1之间,可能存在N=f(N)。

最后得到N=1111111110时,成立。

0 0
原创粉丝点击