您的位置:首页 > 其它

整数中1出现的次数

2015-09-09 16:08 190 查看
以 21345为例,统计1 ~ 21345中1出现的次数。

把21345分成两部分统计:1 ~ 1345 和 1346 ~ 21345

这样一来,如果统计出 1346 ~ 21345中1出现的次数。

1 ~ 1345中1出现的次数,可以看做是21345去掉最高位的子问题,因此可以递归处理。

下面就统计1346~ 21345中1出现的次数。

1. 首先统计最高位出现1的次数:

这里最高位为2,那么最高位为1时,只可能在10000 ~ 19999中,即1出现了10000次

如果最高位是1呢?即11345,那么最高位为1时,只可能在10000 ~ 11345中,即 1出现了1346次

// 最高位出现1的次数
if (first > 1) {
numFirstDigit = (int) Math.pow(10, length - 1);
} else {
numFirstDigit = 1 + Integer.valueOf(str.substring(1));
}

2. 统计其余位出现1的次数
把 11346 ~ 21345 分成两部分:  1346 ~ 11345 和 11346 ~ 21345,每一部分各10000个数。

如果是 11346 ~ 31346,则分成三部分:1346 ~ 11345 、11346 ~ 21345 和21346 ~ 31345,每一部分个10000个数。

即如果最高位是1,则分成1部分,如果最高位是2,则分成两部分,依次类推。

每一部分各10000个数,可以看成4位0~9的十位数的枚举,则1出现了4*1000次。

那么其余位出现1的总次数为:最高位*其余位数*Pow(10,其余位数-1)

// 其余位 出现1的次数
numOtherDigits = first * (length-1)*((int) Math.pow(10, length - 2));

到此1346~ 21345中1出现的次数已经统计完了,递归统计1345、345、45和5,然后累加即可得到结果。

完整代码如下:

public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int first, length;
int numOtherDigits, numRecursive, numFirstDigit;
String str = String.valueOf(n);

first = str.charAt(0) - '0';
length = str.length();

if (1 == length && 0 == first)
return 0;
if (1 == length && first > 0)
return 1;

// 最高位出现1的次数
if (first > 1) {
numFirstDigit = (int) Math.pow(10, length - 1);
} else {
numFirstDigit = 1 + Integer.valueOf(str.substring(1));
}

// 其余位 出现1的次数
numOtherDigits = first * (length-1)*((int) Math.pow(10, length - 2));

// 递归处理
numRecursive = NumberOf1Between1AndN_Solution(Integer.valueOf(str.substring(1)));

return numFirstDigit+numOtherDigits+numRecursive;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: