题目描述:求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
思路:(1)将所有数合并到一个字符串中,并按每个字符拆分到char类型数组中,一次比较每个字符与1是否相等。
(2)依次考察每个数,不断除10,判断每一位是否为1.
(3)递归,总结规律
代码:(1)
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int count = 0;
while(n > 0){
String str = String.valueOf(n);
char[] ch = str.toCharArray();
for(int i = 0; i < ch.length; i++){
if(ch[i] == '1'){
count++;
}
}
n--;
}
return count;
}
}
代码:(2)
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
if(n < 1){
return 0;
}
int count = 0;
for(int i = 1; i <= n; i++){
count += countOne(i);
}
return count;
}
public int countOne(int i){
int count = 0;
while(i != 0){
if((i % 10) == 1){
count++;
}
i /= 10;
}
return count;
}
}
代码:(3)
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
if(n < 1){
return 0;
}
int len = getLenOfNum(n);
if(len == 1){
return 1;
}
int tmp1 = powerBaseOf10(len - 1);
//最高位
int first = n / tmp1;
//如果最高位是1,则最高位为1的数量为除去最高位剩下的数 + 1;不是的话则为10^剩余位数
int firstOneNum = first == 1 ? n % tmp1 + 1 : tmp1;
int otherOneNum = first * (len - 1) * (tmp1 / 10);
//加上剩余部分
return firstOneNum + otherOneNum + NumberOf1Between1AndN_Solution(n % tmp1);
}
public int getLenOfNum(int num){
int len = 0;
while(num != 0){
len++;
num /= 10;
}
return len;
}
//10的base次方
public int powerBaseOf10(int base){
return (int)Math.pow(10, base);
}
}