class Solution {
public int digitOneInNumber(int num) {
int high = num / 10;// 高位
int low = 0;// 低位
int cur = num % 10;// 现位
int bit = 1;// 个位
int ans = 0;
while (high != 0 || cur != 0) {
if (cur == 0) {
ans += high * bit;
} else if (cur == 1) {
ans += high * bit + low + 1;
} else {
ans += (high + 1) * bit;
}
low += cur * bit;
cur = high % 10;
high /= 10;
bit *= 10;
}
return ans;
}
}
class Solution {
public:
int digitOneInNumber(int num) {
int high = num / 10;
int cur = num % 10;
int low = 0;
long digit = 1;
int res = 0;
while (high != 0 || cur != 0) {
if (cur == 0) {
res += high * digit;
}
else if (cur == 1) {
res += high * digit + low + 1;
}
else {
res += (high + 1) * digit;
}
low = cur * digit + low;
cur = high % 10;
high /= 10;
digit *= 10;
}
return res;
}
};
class Solution {
public int digitOneInNumber(int num) {
//cur=n/bit%10
//cur=0 count+=high*low
//cur=1 count+=high*low+1+low
//cur=2-9 count=(high+1)*low
long bit=1;
int sum=0;
while(bit<=num){
long cur=(num/bit)%10;
long high=num/bit/10;
long low=num%bit;
if(cur==0) sum+=high*bit;
else if(cur==1) sum+=high*bit+low+1;
else sum+=(high+1)*bit;
bit*=10;
}
return sum;
}
}
class Solution {
public int digitOneInNumber(int num) {
// 排列组合问题
long bit = 1, low = 0, high = 0, cur = 0, ans = 0;
while (bit <= num) {
cur = (num / bit) % 10;
low = num % bit;
high = num / bit / 10;
if (cur > 1) {
// 右边可以取满
ans += (high + 1) * bit;
} else if (cur == 1) {
// 左边是high的时候,右边只能取到low
ans += high * bit + 1 + low;
} else {
// 左边是high的时候,右边不能取
ans += high * bit;
}
bit *= 10;
}
return (int) ans;
}
}
共以下 9 个回答
时间复杂度O(logn)
空间复杂度O(1)
解题思路
– 每个位置的1要单独计算,比如11要算2次,所以在每个位置单独考虑即可,不用担心数字重复只能算作一份
– 关键是总结第i位出现1的时候会有多少种可能,规律是什么,直接参考题解,https://leetcode.cn/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/solutions/229751/mian-shi-ti-43-1n-zheng-shu-zhong-1-chu-xian-de-2/
– 难点是在于如何获取高位,当前位,低位的在每一次循环时的数据(用n=32104举例)
high
cur
low
digit
当前cur是从右到左第i位对应的10^i
公式
high=high/10
(第一次high=n/10)
cur=high%10
(第一次high=n%10)
low =low +cur*digit
digit =digit *10
第1次循环
32104
32104
0
1
第2次循环
32104
32104
4
10
第3次循环
32104
32104
4
100
第4次循环
32104
32104
104
1000
第5次循环
0
32104
2104
10000
【题解1】
思路:数学推导,按照一个数字的每一位统计 1 的次数。
时间复杂度:O(logn)
空间复杂度:O(logn)
分别计算各位上1的数量,然后求和得到结果。
时间复杂度O(Logn),空间复杂度O(1)。
逐位计算,分三种情况
Ologn o1
//方法1 暴力解(超出时间限制)
class Solution {
public int digitOneInNumber(int num) {
int result = 0;
for (int i = num; i >= 0; i–) {
result+=one_numlen(i);
}
return result;
}
}
//方法2
class Solution {
public int digitOneInNumber(int num) {
int result = 0;
long factor = 1; // 使用 long 类型防止溢出
}