更多2019年的技術文章,歡迎關注我的微信公衆號:碼不停蹄的小鼠松(微信號:busy_squirrel),也可掃下方二維碼關注獲取最新文章哦~
T:
題目描述
求出113的整數中1出現的次數,並算出1001300的整數中1出現的次數?爲此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數。
兩種解決方式:找規律和暴力遍歷
- 暴力遍歷
化爲字符串,或者用10取餘,都是一樣的道理:
code:
/**
* 通過統計字符串的方式,計算其包含有多少個1
* @param n
* @return
*/
public int test(int n) {
int count = 0;
for (int i = 0; i <= n; i++) {
String ss = String.valueOf(i);
for (int j = 0; j < ss.length(); j++) {
if (ss.charAt(j) == '1') {
count ++;
}
}
}
return count;
}
- 找規律
這個規律還真的不好找,我用了好幾張稿紙,纔算弄出來。。。
具體的細節或者規律的推導過程這裏不講了,就貼我在討論班上的留言吧:
code:
/**
* T: 整數中1出現的次數(從1到n整數中1出現的次數)
*
* 題目描述 求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?
* 爲此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,
* 但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,
* 可以很快的求出任意非負整數區間中1出現的次數。
*
* date: 2015.11.19 19:22
* @author SSS
*
*/
public class Solution {
/**
* 通過找規律求解
* 這個規律真心不好找。。。
* @param n
* @return
*/
public int NumberOf1Between1AndN_Solution(int n) {
int count = 0;
if (n == 0) {
return count;
}
// 該數的長度
int size = 0;
int tempN = n;
while ((int)(tempN / Math.pow(10, size)) != 0) {
size ++;
}
// 標準值,即9,99,999,9999,……中含有多少個1
int []F = new int[size + 1]; // 下標爲0的地方空出來
F[0] = 0; // 基本用不着
F[1] = 1;
for (int i = 2; i < F.length; i++) {
F[i] = (int) (10 * F[i - 1] + Math.pow(10, i - 1));
}
int []arr = new int[size + 1];
tempN = n;
int tempK = 0;
// 數字倒着放在數組中,便於計算
while (tempK < size) {
arr[size - tempK] = (int) (tempN / Math.pow(10, size - tempK - 1));
tempN = (int) (tempN % Math.pow(10, size - tempK - 1));
tempK ++;
}
int []f = new int[size + 1];
// 先確定起點
if (arr[1] > 0) {
f[1] = 1;
} else {
f[1] = 0;
}
for (int i = 2; i < f.length; i++) {
f[i] = arr[i] * F[i - 1] + f[i - 1];
int tail;
int tailNum = (int) (n % Math.pow(10, i - 1));
if (arr[i] == 0) {
tail = 0;
} else if (arr[i] == 1) {
tail = tailNum + 1;
} else {
tail = (int) Math.pow(10, i - 1);
}
f[i] += tail;
}
count = f[size];
return count;
}
}
更多2019年的技術文章,歡迎關注我的微信公衆號:碼不停蹄的小鼠松(微信號:busy_squirrel),也可掃下方二維碼關注獲取最新文章哦~