本文首發于我的個人博客:尾尾部落
題目描述
求出113的整數中1出現的次數,并算出1001300的整數中1出現的次數?為此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對于后面問題他就沒轍了。ACMer希望你們幫幫他,并把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數(從1 到 n 中1出現的次數)。
解題思路
三種解法:
- 法一:依次遍歷每個數,判斷每個數里面是否包含1
- 法二:同法一,將數字轉成字符串,直接判斷
- 法三:歸納法
設N = abcde ,其中abcde分別為十進制中各位上的數字。
如果要計算百位上1出現的次數,它要受到3方面的影響:百位上的數字,百位以下(低位)的數字,百位以上(高位)的數字。
① 如果百位上數字為0,百位上可能出現1的次數由更高位決定。比如:12013,則可以知道百位出現1的情況可能是:100199,11001199,21002199,,...,1110011199,一共1200個。可以看出是由更高位數字(12)決定,并且等于更高位數字(12)乘以 當前位數(100)。
② 如果百位上數字為1,百位上可能出現1的次數不僅受更高位影響還受低位影響。比如:12113,則可以知道百位受高位影響出現的情況是:100199,11001199,21002199,,....,1110011199,一共1200個。和上面情況一樣,并且等于更高位數字(12)乘以 當前位數(100)。但同時它還受低位影響,百位出現1的情況是:12100~12113,一共114個,等于低位數字(113)+1。
③ 如果百位上數字大于1(29),則百位上出現1的情況僅由更高位決定,比如12213,則百位出現1的情況是:100199,11001199,21002199,...,1110011199,1210012199,一共有1300個,并且等于更高位數字+1(12+1)乘以當前位數(100)。
——參考牛客網@藍裙子的百合魂
參考代碼
法一:
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int res = 0;
for(int i = 1; i <= n; i++)
res += number1(i);
return res;
}
public int number1(int n){
int res = 0;
while(n>0){
if(n % 10 == 1)
res++;
n /= 10;
}
return res;
}
}
法二:
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int res = 0;
StringBuffer s = new StringBuffer();
for(int i = 1; i<=n; i++){
s.append(i);
}
String str = s.toString();
for(int i=0; i<str.length(); i++){
if(str.charAt(i) == '1')
res++;
}
return res;
}
}
法三:
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int res = 0;
int cur = 0, before = 0, after = 0;
int i = 1;
while(i<=n){
before = n/(i*10);
cur = (n/i)%10;
after = n - n/i*i;
if(cur == 0){
// 如果為0,出現1的次數由高位決定,等于高位數字 * 當前位數
res += before * i;
}else if(cur == 1){
// 如果為1, 出現1的次數由高位和低位決定,高位*當前位+低位+1
res += before * i + after + 1;
}else{
// 如果大于1, 出現1的次數由高位決定,(高位數字+1)* 當前位數
res += (before + 1) * i;
}
i *= 10;
}
return res;
}
}