編寫一個方法,數出從0到n中數字2出現了幾回?
例如:若是n爲20,那麼0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 中共2共出現了3次。git
一、暴力方法,數出每一個數字包含幾個2,而後累加起來。測試
二、分析:分別考慮數字n每一位出現2的次數,如123123;spa
從左往右考慮4123123;it
考慮第一個1(即第6位),該位出現2的次數爲4*10^6/10;class
考慮第一個2(即第5位),該位出現2的次數爲41*10^5/10+3123+1;方法
考慮第一個3(即第4位),該位出現2的次數爲(412+1)*10^4/10;總結
附:除以10的緣由在於:每10個數字,任意位出現2的機率爲1/10.next
總結規律:static
第i位出現2個次數與該位所在的數字有關:di
當第i位的數字小於2,出現次數就等於比其高位部分的數字*10^i/10,
當第i位的數字等於2,出現次數就等於比其高位部分的數字*10^i/10+n%(10^i),
當第i位的數字大於2,出現次數就等於(比其高位部分的數字+1)*10^i/10。
// 計算1-n中1出現的次數
public class CountOne {
// 思路:分別計算「1」在每一個位上面出現的次數,疊加起來
public static int countNumOf1(int n) {
if (n <= 0) {
return 0;
}
int count = 0;
int factor = 1;
while(n / factor != 0) {
int lowerNum = n - n / factor * factor;
int currentNum = (n / factor) % 10;
int highNum = n / (factor * 10);
if (currentNum == 0) {
// 若是爲0,出現1的次數由高位決定
count += highNum * factor;
} else if (currentNum == 1) {
// 若是爲1,出現1的次數由高位和低位決定
count += highNum * factor + lowerNum + 1;
} else {
// 若是大於1,出現1的次數由高位決定
count += (highNum + 1) * factor;
}
factor *= 10;
}
return count;
}
public static void main(String[] args) {
// 測試
System.out.println(countNumOf1(13));
System.out.println(countNumOf1(23));
System.out.println(countNumOf1(33));
System.out.println(countNumOf1(93));
System.out.println(countNumOf1(123));
}
}