您的位置:首页 > 其它

【LeetCode】233. Number of Digit One

2015-07-13 12:26 555 查看
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.

Hint:

Beware of overflow.

难题的惯例是先上保底做法。逐个数字数1,累加。

虽然知道会TLE,总比空着白板好。

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


下面上标准做法,参考了编程之美。

这题可以扩展为其他进制的情况。

从右到左逐位计数当前位置(记为cur)为1的所有数字。

(1)cur为0时,需要计数的部分为:cur位置为1,然后对于高位0~high-1的每个值,低位遍历0~divisor。

因此总数为high * divisor

(2)cur为1时,需要计数的部分为:除了上述cur为0的部分,再补充cur为1时,低位遍历0~low。

因此总数为high * divisor + low + 1

(3)cur为其他数时,需要计数的部分为:

cur位置为1,然后对于高位0~high的每个值,低位遍历0~divisor。

因此总数为(high + 1) * divisor

class Solution {
public:
int countDigitOne(int n) {
if(n <= 0)
return 0;
int ret = 0;
int base = 10;
long long divisor = 1;
while(n / divisor)
{
int high = n / (divisor * base);
int cur = n / divisor % base;
int low = n - n / divisor * divisor;
if(cur == 0)
ret = ret + high * divisor;
else if(cur == 1)
ret = ret + high * divisor + low + 1;
else
ret = ret + (high + 1) * divisor;
divisor *= base;
}
return ret;
}
};


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: