持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
题目(Number of Digit One)
链接:https://leetcode-cn.com/problems/number-of-digit-one
解决数:569
通过率:48.6%
标签:递归 数学 动态规划
相关公司:microsoft google amazon
给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。
示例 1:
输入: n = 13
输出: 6
示例 2:
输入: n = 0
输出: 0
提示:
0 <= n <= 109
思路
归纳法,对于个位出现的1:(n / 10) * 1 + (n % 10) >= 1 ? 1 : 0; 对于十位出现的1:(n / 100) * 10 + if (k > 19) 10 else if (k < 10) 0 else k - 10 + 1; 对于百位出现的1:(n / 1000) * 100 + if (k > 199) 10 else if (k < 100) 0 else k - 100 + 1; 最终归纳出: (n / (i * 10)) * i + if (k > 2 * i - 1) i else if (k < i) 0 else k - i + 1, 其中k = n % (i * 10);
代码
var countDigitOne = function(n) {
let count = 0;
for (let i = 1; i <= n; i *= 10) {
let divide = i * 10;
let p = Math.floor(n / divide), k = n % divide, rest = 0;
count += p * i;
rest = (k > (2 * i - 1)) ? i : ((k < i) ? 0 : k - i + 1);
count += rest;
}
return count;
};
思路2
数学题解,枚举每一数位上 1 的个数
function countDigitOne(n: number): number {
let count = 0;
for (let i = 1; i <= n; i *= 10) {
const divide = i * 10;
const p = Math.floor(n / divide),
k = n % divide;
let rest = 0;
count += p * i;
rest = k > 2 * i - 1 ? i : k < i ? 0 : k - i + 1;
count += rest;
}
return count;
}
其他思路
主要的解题思路是分为3种情况:
-
当前位数值等于0场景 举个例子:201 十位是0的场景,把十位置为1,看百位、个位,即:010~119(十位为1时,百位不可能为2);个数为2 * 10 = 20,2为百位数值(0和1两种情况),10位当前位阶十位;
-
当前位数值等于1场景 举个例子:213 十位是1的场景,把十位置为1,看百位、个位,即:010~213(十位为1时,百位不可能为2);个数为2 * 10 + 13 + 1 = 33,2为百位数值(0和1两种情况),10位当前位阶十位,13 + 1为210~213的数量;
-
当前位数值大于1场景 举个例子:263 十位是大于1的场景,把十位置为1,看百位、个位,即:010~219(十位为1时,百位不可能为2);个数为2 * 10 + 10 = 30,2为百位数值(0和1两种情况),10位当前位阶十位,10为当前位阶,即210~219的数量;
代码
/**
* @param {number} n
* @return {number}
*/
var countDigitOne = function(n) {
let x = 1;
let count = 0;
for(let i = 0; n >= x; i+=1){
let s = Math.floor(n%(x*10)/x);
// 当前位是0的情况
if( s === 0){
// 左侧相邻高一位数 * 当前位阶
count += Math.floor(n/(x*10)) * x;
}
// 当前位是1的情况
if(s === 1){
// 左侧相邻高一位数 * 当前位阶 + 右侧所有低位数 + 1
count += Math.floor(n/(x*10)) * x + n%x + 1;
}
// 当前位是大于1的情况
if(s > 1){
// 左侧相邻高一位数 * 当前位阶 + 当前位阶
count += Math.floor(n/(x*10)) * x + x;
}
x *= 10
}
return count;
}