整数中1出现的次数(剑指offer-31)
题目描述
求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
题目解析
方法一:暴力1-n个数字即可。时间复杂度O(n*log(n))
方法二:通过对1-n的分区间讨论(递归的过程),在求1-n的时候,分为两个区间,第一个区间是1-b(b是n去掉首部数字之后的数字), 第二个区间是(b+1, n)。对于每个区间的计算时,分为了两种情况,第一种情况是当前n的首部数字是1,第二种情况是除了首位的其他位是1。主要是这两中情乱的讨论。
题目解答
public int NumberOf1Between1AndN_Solution(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
int x = i;
while (x != 0) {
if (x % 10 == 1) {
sum++;
}
x = x / 10;
}
}
return sum;
}
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
if(n==0) return 0;
String str = ""+n;
int len = str.length();
if(len == 1) return 1;
int res = (int)Math.pow(10,len-1);//获取n的幂级
int firstNumber = n / res;
int firstBit = firstNumber==1? (n%res)+1:res;
//(len - 1)的意思就是剩余位的个数(C(len-1, 1) -> 从剩余的len-1位中选取一位来作为1),
//res/10的意思就是剩余的len-2位可能出现的情况
int otherBit = (len-1)*firstNumber*res/10;
return firstBit + otherBit + NumberOf1Between1AndN_Solution(n%res);
}
}
Stay hungry,Stay foolish