0-n之间的1的个数何时等于n(Java程序员面试宝典)

Consider a function which ,for a given whole number n, returns the number of ones required when writing out all numbers between 0 and n.

for example, f(13)=6. notice that f(1)=1. what is the next largest n such that f(n)=n?

有一个整数n,写一个函数f(n),返回0-n之间出现的"1"的个数。比如f(1)=1,f(13)=6(1、10、11、12、13一共6个1),问一个最大的f(n)=n中的n是多少?

这个题目的关键在于效率上,可以采用缓存的机制。可以吧前面的计算结果缓存下来,把每次的结果保存好,就不用每次都从新计算,从而可以提高效率。例如计算1-101,只要把之前1-100的结果与101的个数相加就行了。

代码如下:

public class Example_1 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		int n = 2;
		int res = 1;
		while((getOne(n) + res) != n)
		{
			res += getOne(n);
			System.out.println("0到"+n+"之间的1的个数为:"+res);
			++n;
		}
		long endTime = System.currentTimeMillis();
		System.out.println("计算所消耗时间为:"+(endTime - startTime)/1000+"s");
		System.out.println(n);
	}

	private static int getOne(int n) {
		int num = 0;
		String s = n+"";
		int len = s.length();
		if(len != 0)
		{
			for(int i = 0;i < len; i++)
			{
				char c = s.charAt(i);
				if(c == '1')
				{
					num++;
				}
			}
		}
		return num;
	}

}

运行结果如下:

......................................................
0到199907之间的1的个数为:199889
0到199908之间的1的个数为:199890
0到199909之间的1的个数为:199891
0到199910之间的1的个数为:199893
0到199911之间的1的个数为:199896
0到199912之间的1的个数为:199898
0到199913之间的1的个数为:199900
0到199914之间的1的个数为:199902
0到199915之间的1的个数为:199904
0到199916之间的1的个数为:199906
0到199917之间的1的个数为:199908
0到199918之间的1的个数为:199910
0到199919之间的1的个数为:199912
0到199920之间的1的个数为:199913
0到199921之间的1的个数为:199915
0到199922之间的1的个数为:199916
0到199923之间的1的个数为:199917
0到199924之间的1的个数为:199918
0到199925之间的1的个数为:199919
0到199926之间的1的个数为:199920
0到199927之间的1的个数为:199921
0到199928之间的1的个数为:199922
0到199929之间的1的个数为:199923
0到199930之间的1的个数为:199924
0到199931之间的1的个数为:199926
0到199932之间的1的个数为:199927
0到199933之间的1的个数为:199928
0到199934之间的1的个数为:199929
0到199935之间的1的个数为:199930
0到199936之间的1的个数为:199931
0到199937之间的1的个数为:199932
0到199938之间的1的个数为:199933
0到199939之间的1的个数为:199934
0到199940之间的1的个数为:199935
0到199941之间的1的个数为:199937
0到199942之间的1的个数为:199938
0到199943之间的1的个数为:199939
0到199944之间的1的个数为:199940
0到199945之间的1的个数为:199941
0到199946之间的1的个数为:199942
0到199947之间的1的个数为:199943
0到199948之间的1的个数为:199944
0到199949之间的1的个数为:199945
0到199950之间的1的个数为:199946
0到199951之间的1的个数为:199948
0到199952之间的1的个数为:199949
0到199953之间的1的个数为:199950
0到199954之间的1的个数为:199951
0到199955之间的1的个数为:199952
0到199956之间的1的个数为:199953
0到199957之间的1的个数为:199954
0到199958之间的1的个数为:199955
0到199959之间的1的个数为:199956
0到199960之间的1的个数为:199957
0到199961之间的1的个数为:199959
0到199962之间的1的个数为:199960
0到199963之间的1的个数为:199961
0到199964之间的1的个数为:199962
0到199965之间的1的个数为:199963
0到199966之间的1的个数为:199964
0到199967之间的1的个数为:199965
0到199968之间的1的个数为:199966
0到199969之间的1的个数为:199967
0到199970之间的1的个数为:199968
0到199971之间的1的个数为:199970
0到199972之间的1的个数为:199971
0到199973之间的1的个数为:199972
0到199974之间的1的个数为:199973
0到199975之间的1的个数为:199974
0到199976之间的1的个数为:199975
0到199977之间的1的个数为:199976
0到199978之间的1的个数为:199977
0到199979之间的1的个数为:199978
0到199980之间的1的个数为:199979
计算所消耗时间为:3s
199981

以上代码是书中给出的解法,至于有没有效率更高的解法,等我想到了再来补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值