剑指offer:从1到n整数中1出现的次数(java)
来源:互联网 发布:淘宝休闲女装棉衣 编辑:程序博客网 时间:2024/05/16 10:06
题目:输入一个整数n,求从1到n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11,和12,1一共出现了5次。
不考虑时间效率的解法,靠它想拿offer有点难
如果在面试的时候碰到这个问题,应聘者大多能想到最直观的方法,也就是累加1到n中每个整数1出现的次数。我们可疑每次通过对10求余数判断整数的个位数字是不是1.如果这个数字大于10,除以10之后再判断个位数字是不是1.
public int numberOf1BetweenAndN(int n){ int number = 0; for(int i = 1;i<= n;i++){ number+=numberOf1(i); } return number; } public int numberOf1(int n){ int number =0; while(n!=0){ if(n %10 == 1) number++; n = n/10; } return number; }从上述思路中,我们对每个数字都要做出发和求余运算以求出该数字中1出现的次数。如果输入数字n,n有O(logn)位,我们需要判断每一位是不是1,那么它的时间复杂度是O(n*logn)。当输入n非常大的时候,需要大量的计算,运算效率不高。面试官不会满意这种算法
从数字规律着手明显提高时间效率的解法,能让面试官耳目一新
如果希望不用计算每个数字的1的个数,那就只能寻找1在数字中出现的规律了。为了找到规律,我们不妨用一个稍微大一点的数字比如21345作为例子来分析。我们把从1到21345的所有数字分为两段,一段是从1到1345,另一段是从1346到21345.划分的原因是便于利用递归的思路,因为21345去掉最高位就是1345.我们先看1346到21345中1出现的次数。1的出现分为两种情况:1出现在最高位和1出现在其他位。1346到21345,1出现在10000-19999这10000个数字的最高位中,一共出现了10000个,即10^最高位。我们可以发现一般情况:如果是1346到11345,1出现在10000-11345的最高位中,一共出现2346次,也就是除去最高数字之后剩下的数字+1,当万位大于1时,1出现在最高位的次数是10^最高位。
接下来分析1出现在除最高位之外的其他四位数中的情况。1346-21345这20000个数字中后4位出现的次数,分成两段,1346-11345和11346-21345,每一段剩下的4位数字中,选择其中一位是1,其余三位可以在0-9这10个数字中任意选择,根据排列组合原则,总共出现次数2*4*10^3=8000次。我们可以发现一般情况:如果是1346-n1345那么,可以划分为n段,即1出现在除最高位之外的其他四位数的次数是n*4*1000;
public static int numberOf1BetweenAndN(int n){ if(n<=0){return 0;}String str=n+""; return numberOf1(str); } public static int numberOf1(String str){ char[] strN=str.toCharArray(); int length=strN.length; if(length==1&&strN[0]=='0'){ return 0; } if(length==1&&strN[0]>'1'){ return 1; } int numFirstDigit=0; if(strN[0]>'1') numFirstDigit=(int) Math.pow(10,length-1); else if(strN[0]=='1') numFirstDigit=Integer.parseInt(str.substring(1))+1; int numOtherDigits=(int) ((strN[0]-'0')*(length-1)*Math.pow(10, length-2)); int numRecursive=numberOf1(str.substring(1)); return numFirstDigit+numOtherDigits+numRecursive; }
- 剑指offer:从1到n整数中1出现的次数(java)
- 《剑指offer》整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer--整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指Offer--032-整数中1出现的次数(从1到n整数中1出现的次数)
- [剑指offer]整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer-整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指Offer:整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer:整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer----整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer-整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer 整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer-31.整数中1出现的次数(从1到n整数中1出现的次数)
- 【剑指offer】整数中1出现的次数(从1到n整数中1出现的次数)
- 《剑指offer》整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer:整数中1出现的次数(从1到n整数中1出现的次数)
- 整数中1出现的次数,即从1到n整数中1出现的次数(剑指Offer)
- 【剑指offer-Java版】32从1到n的整数中1出现的次数
- 剑指offer(33):从1到n整数中1出现的次数
- [POJ]1970 The Game (DFS搜八连通的连通块)
- n皇后问题
- U-boot2010代码框架
- 【AC自动机】目录
- 信息流zt_使用json参数拼接sql语句
- 剑指offer:从1到n整数中1出现的次数(java)
- 大数据平台架构收集和整理
- hdu5914 构造
- 计算逆矩阵
- C1GridView1 AllowAutoSort 自动排序
- Days 25 LruCache缓存处理&Bitmap二次采样
- 【NOIP2016提高A组五校联考2】string
- 计算机系统内部五大部件的主要连接关系总结
- MYSQL syntax error 1064