值得推荐。 |
---|
题目:
输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。
例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。
示例 1:
输入:n = 12
输出:5
示例 2:
输入:n = 13
输出:6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析:
本题采用分而治之,根据某一位上数字的情况进行划分
例如:
1、举个栗子, 假如 n = 12x45, 现在要统计1~12x45在第 x 位上 1 的数目, 显然这里分为三种情况:
x = 0: 此时对于1 ~ 12045这些数字,要想在x这一位上是 1, 那么前两位的范围只能是 0 ~ 11, 而后两位的范围则可以是 0~99, 只考虑该位上的 1, 那么它的数目就是左右取值范围的乘积, 也即 12100;
x = 1: 此时对于1 ~ 12145这些数字显然仍包含第一种情况中的可能性, 但它有额外的部分, 也即前两位可以是 12, 然后后面的范围是 0~45, 加起来就是12100 + 146个 ;
x > 1: 举个例子比如12745,此时对于1 ~ 12745这些数字仍包含第一种情况中的可能性, 但对于前两位是 12 来说, 后面的取值范围就是 0~99 了(12100 ~ 12199), 所以加起来就是12100 + 1*100个;
综合这三种情况, 就能够计算出每一位上的 1 的数目, 最后累加起来就是总的 1 的数目
代码实现:
class Solution {
public int countDigitOne(int n) {
//index为位,1代表个位,10代表十位
int index = 1;
int count = 0;
int high = n;
int cur = 0;
int low = 0;
//由于high = n /(index*10) 中index *10 很容易越位,不直接使用这种表达方式
while(high > 0){
// high为X左边的高位数字
high /= 10;
// cur为当前位上的数字
cur = (n / index) % 10;
// low为X右边的低位数字
low = n - (n / index) * index;
//以下是计算的公式
if(cur == 0) count += high * index;
if(cur == 1) count += high * index + low + 1;
if(cur > 1) count += (high+1) * index;
index *= 10;
}
return count;
}
}
推荐参考:
Java100%
python style