# Leetcode233-Number of Digit One

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

For example:

Given n = 13,

Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

## 分析

class Solution {
public:
int countDigitOne(int n) {
int count = 0;
for (int i = 1; i <= n; ++i) {
int num = i;
while (num) {
if (num % 10 == 1) {
++count;
}
num /= 10;
}
}
return count;
}
};

• 首先是个位。
• 1,11,21,31,41,51,61,71,81,91,101,111,121。不难发现是12+1个“个位”的1。
• 十位。
• 10,11,12,13,14,15,16,17,18,19,110,111,112,113,114,115,116,117,118,119。2*10个“十位”的1。
• 不难发现对于第i位。
• 我们记数字n = a(m) * 10^m + a(m-1) * 10^(m-1) + ... + a(0) * 10^0
• 并记p和q分别为第i位前的数和第i位后的数。
• p = a(m) * 10^(m-i-1) + ... + a(i+1) * 10^0
• q = a(i-1) * 10^(i-1) + ... + a(0) * 1
• 再记第i位数字为k。
• 第i位的1的个数：p * 10^(i-1) + if (k == 1) { (q+1); } + if (k > 1) { 10^(i-1); }
• 如数字83121＝8 * 10000 + 3 * 1000 + 1*100 + 2 * 10 + 1 * 1, 对第三位（第三位为1）有p＝83，q=21，k=1。第3位的1的个数为83 * 100 + 21 + 1 ＝ 8322
• 不难发现时间复杂度为O(logn)

## AC代码

class Solution {
public:
int countDigitOne(int n) {
int count = 0, previous = 0, coef = 1;
while (n) {
int remain = n % 10;
int over = n / 10;
if (remain > 1) {
count += coef;
} else if (remain == 1) {
count += previous + 1;
}
count += coef * over;
previous += coef * remain;
coef *= 10;
n /= 10;
}
return count;
}
};

#### hdu1060-Leftmost Digit

2013-06-09 14:35:18

#### 杭电OJ1061-Rightmost Digit

2016-08-08 20:37:29

#### XTU 1227 Digit

2016-05-31 22:37:31

#### hdoj1060Leftmost Digit

2016-03-20 21:47:40

#### NYOJ1061Rightmost Digit

2014-11-06 22:15:41

#### leetcode 233: Number of Digit One

2015-07-08 07:53:14

#### 233 - Number of Digit One

2015-08-07 18:03:22

#### 错误：error C2153:hex constants must have at least one hex digit

2012-01-29 17:01:21

#### 剑指offer 面试题32：从1到n整数中1出现的次数(leecode233. Number of Digit One) 题解

2016-05-04 00:47:45

#### LeetCode-Number of Digit One-解题报告

2015-07-09 14:04:11