class Solution {
public int digitOneInNumber(int num) {
int res = 0;
//所有位上1的个数和为1出现的次数
int bit = 1;
int high = num/10;
int low = 0;
int cur = num%10;
while (high != 0 || cur != 0) {
if (cur 0) {
res += high * bit;
} else if (cur 1) {
res += high * bit + low + 1;
} else {
res += (high + 1) * bit;
}
low += cur * bit;
cur = high%10;
high = high/10;
bit =bit * 10;
}
return res;
}
class Solution {
public int countDigitOne(int n) {
long count=0;
long bit = 1;
while(bit<=n){
long cur = (n/bit)%10;
long high=n/bit/10;
long low =n%bit;
if(cur>1){
count+=(high+1)bit;
}else if(cur1){
count += (highbit)+(low+1);
}else{
count += highbit;
}
bit = bit10;
}
return (int)count;
}
}
时间复杂度O(logn)
空间为o(1)
java
class Solution {
public int countDigitOne(int n) {
//思路:分别找到1-n的个位、十位、百位...的1的出现次数相加,即为1出现的总次数
//分为三种情况,当当前位为0时,当前位为1时,当前位为2,3,4...9时的情况
int digit = 1; //位因子,表示当前位
int high = n / 10; //n的高位
int low = 0; //n的低位
int cur = n % 10; //当前位
int res = 0;
while(high != 0 || cur != 0) {
if(cur == 0) {
res += high * digit;
} else if(cur == 1) {
res = res + high * digit + low + 1;
} else {
res += (high + 1) * digit;
}
low += cur * digit;
cur = high % 10;
digit *= 10;
high /= 10;
}
return res;
}
}
“`C++
int countOnes(int n) {
int count = 0;
for (int i = 1; i <= n; i++) {
int num = i;
while (num > 0) {
if (num % 10 == 1) {
count++;
}
num /= 10;
}
}
return count;
}
“`
class Solution {
public int countDigitOne(int n) {
long bit = 1;
long sum = 0;
while(bit <= n){
long cur = (n / bit) % 10;
long low = n % bit;
long high = n / bit / 10;
if(cur > 1){
sum += (high + 1) * bit;
}else if(cur == 1){
sum += (high * bit) + (1 + low);
}else{
sum += high * bit;
}
bit = bit * 10;
}
return (int)sum;
}
}
// 1~n 整数中 1 出现的次数
// 时间复杂度 O(logN)
// 空间复杂度 O(1)
class Solution {
public:
int countDigitOne(int n) {
int high = n / 10;
int cur = n % 10;
int low = 0;
long long res = 0;
long long digit = 1;
while (high || cur) {
if (cur == 0) {
res += high * digit;
}
else if (cur == 1) {
res += high * digit + low + 1;
}
else {
res += (high + 1) * digit;
}
digit *= 10;
cur = high % 10;
high /= 10;
low = n % digit;
}
return res;
}
};
class Solution:
def countDigitOne(self, n: int) -> int:
bit = 1
cntOne = 0
while bit <= n:
cur = n // bit % 10
low = n % bit
high = n // (bit * 10)
if cur > 1:
cntOne += (high + 1) * bit
elif cur == 1:
cntOne += high * bit + (low + 1)
else:
cntOne += high * bit
bit *= 10
return cntOne
class Solution {
public int countDigitOne(int n) {
long mulk = 1;
int ans = 0;
for (int k = 0; n >= mulk; ++k) {
ans += (n / (mulk * 10)) * mulk + Math.min(Math.max(n % (mulk * 10) - mulk + 1, 0), mulk);
mulk *= 10;
}
return ans;
}
}
class Solution {
public:
int countDigitOne(int n) {
long b=1;
int ans=0;
while(b<=n){
int cur = n/b%10;
if(cur>1)
ans += (n/(b*10)+1) * b;
else if(cur==1)
ans += n/(b*10)*b+(1+n%b);
else
ans += n/(b*10)*b;
b=b*10;
}
return ans;
}
};
public int countDigitOne(int n) {
// 几个公示 计算当前bit 1的个数
// cur > 1 => (high + 1) * bit
// cur == 1 => (high * bit) + (1 + low)
// cur = 0 => high * bit
int res = 0;
int high = n / 10;
int bit = 1; // 从个位开始
int cur = n % 10; // 跟随bit位数
int low = 0; // 一开始low比个位小,所以是无
while(bit <= n) {
if(cur == 0) {
res += high * bit;
} else if(cur == 1) {
res += (high * bit) + (1 + low);
} else { // cur > 1情况
res += high * bit + bit;
}
low += cur * bit;
cur = high % 10;
high = high / 10;
bit = bit * 10;
}
return res;
}
class Solution{
public:
int countDigitOne(int n){
long long bit =1;
long long sum =0;
while(bit <= n){
long long cur = (n/bit) % 10;
long long low = n% bit;
long long high = n/bit/10;
if(cur>1){
sum +=(hign+1)*bit;
}else if(cur == 1){
sum += high *bit + low +1;
}else{
sum += high *bit;
}
bit *=10;
}
return sum;
}
};
//法一 数位dp 时间复杂度:O(n) 空间复杂度:O(1)
class Solution {
public:
int countDigitOne(int n) {
long base = 1;
int res = 0;
while (base <= n) {
int low = n % base;
int high = n / base;
int cur = high % 10;
high /= 10;
// 此时数据按位构成high cur low三部分, 如例一中high = 3101, cur = 6, low = 92
if (cur > 1) res += (high + 1) * base; // base就是举例中的100 1000 10000
else if (cur == 1) res += (low + 1) + high * base;
else res += high * base;
base *= 10;
}
return res;
}
};
//法二 暴力法超时
class Solution {
public:
int countDigitOne(int n) {
int count = 0;
for (int i = 1; i <= n; i++) {
count += countOne(i);
}
return count;
}
int countOne(int n) {
int num = 0;
while (n) {
if (n % 10 == 1) {
num++;
}
n /= 10;
}
return num;
}
};
共以下 19 个回答
“`java
class Solution {
public int digitOneInNumber(int num) {
int res = 0;
//所有位上1的个数和为1出现的次数
int bit = 1;
int high = num/10;
int low = 0;
int cur = num%10;
while (high != 0 || cur != 0) {
if (cur 0) {
res += high * bit;
} else if (cur 1) {
res += high * bit + low + 1;
} else {
res += (high + 1) * bit;
}
}
class Solution {
public int countDigitOne(int n) {
long count=0;
long bit = 1;
while(bit<=n){
long cur = (n/bit)%10;
long high=n/bit/10;
long low =n%bit;
if(cur>1){
count+=(high+1)bit;
}else if(cur1){
count += (highbit)+(low+1);
}else{
count += highbit;
}
bit = bit10;
}
return (int)count;
}
}
时间复杂度O(logn)
空间为o(1)
空间复杂度O(N), 时间复杂度是n的位数,即log10N O(logN)
C++实现
“`C++
int countOnes(int n) {
int count = 0;
for (int i = 1; i <= n; i++) { int num = i; while (num > 0) {
if (num % 10 == 1) {
count++;
}
num /= 10;
}
}
return count;
}
“`
找规律
数位dp
找规律
分类讨论
【思路】将一个数字的每一位拆分,分别去计算每一位的1的个数
【复杂度】时间复杂度O(logn),空间O(1)
官解
时间:O(logn)
空间:O(1)
MY每一位上的1相加
思路:根据高低位和当前位的关系,计算每位对1出现的数量
时间复杂度:O(logn) 空间复杂度:O(1)
竖向考虑每一位的情况。
时间复杂度:O(logn)
空间复杂度:O(1)
时间复杂度:O(logn)
空间复杂度:O(1)
时间复杂度:O(logn)
空间复杂度:O(1)