LeetCode-233.Number of Digit One

来源:互联网 发布:怎么在淘宝卖耐克正品 编辑:程序博客网 时间:2024/05/18 02:42

https://leetcode.com/problems/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:

  1. Beware of overflow.

如果不用暴力求解,显然需要找寻规律

方法一

拿n=21345作为例子分析:

可以将n分为三部分:0-(0)1345,1346-11345和11346-21345

第一部分0-(0)1345可以递归求解21345-20000得结果

第二、三部分分别求(设n最高位是n0

小于n中当最高位为1得,一共出现10000-19999共10000次,这是因为n0=2,如果n0=1(如11345),则出现11345-10000+1次

剩下分析除n0外其它四位情况,后四位可以任选一位是1,其余可以在0-9选择。因此是4*1000次,因为是两部分,所以*2

更详细分析参考《剑指Offer》P175

int countDigitOne(int n)     {        if (n < 1)    return 0;    int n0, len,res = 0,num;//n0记录最高位,len记录位数    while (n>0)    {    if (n < 10)    {    res++;    break;    }    n0 = n;    len = 0;    while (n0 / 10 > 0)    {    n0 /= 10;    len++;    }    num = pow(10, len);    if (n0 == 1)//计算最高位出现1个个数    res += n - num + 1;    else    res += num;    res += n0*len*(num / 10);//括号是防止溢出    n -= n0*num;    }    return res;    }

方法二、

分别讨论每一位为1的情况

参考 https://discuss.leetcode.com/topic/18054/4-lines-o-log-n-c-java-python

int countDigitOne(int n)     {        int res = 0, a, b;    for (long m = 1; m <= n; m *= 10)    {    a = n / m;    b = n % m;    res+= (a + 8) / 10 * m + (a % 10 == 1) * (b + 1);    }    return res;    }

例:

 以百位上1为例子: 假设百位上是0, 1, 和 >=2 三种情况: 

case 1: n=3141092, a= 31410, b=92. 计算百位上1的个数应该为 3141 *100 次

case 2: n=3141192, a= 31411, b=92. 计算百位上1的个数应该为 3141 *100 + (92+1) 次

case 3: n=3141592, a= 31415, b=92. 计算百位上1的个数应该为 (3141+1) *100 次

 以上三种情况可以用 一个公式概括: (a + 8) / 10 * m + (a % 10 == 1) * (b + 1);

0 0
原创粉丝点击