Number of Digit One(leetcode 233)

来源:互联网 发布:补水精华液知乎 编辑:程序博客网 时间:2024/05/21 09:21

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.


1。 最笨方法, 从1到n,看一看每个数有多少个1,最后相加。超时
2。 有规律的
一位数中1个数 1
两位数中1个数 一位数*10 + 一位数个数(10的一次方)
三位数中1个数 两位数*10 + 两位数个数(10的二次方)

如果某一位为0 跳过
为1 为低位数的和+1
》=2 为 n*第几位
。。。。。。。。。。。。。。

对整数 abcdef
就是 0-f 中 1 + 0-e*10 中1 + 0- c* 10* 10 中1 。。。

class Solution {public:    int countDigitOne(int n) {        if (n <= 0) {            return 0;        }        vector<int> c;   // c[1]   一位数中1的个数        // c[2]  两位数中1个数   。。。。。        vector<int> num;    //输入的数转化为倒序int数组        int total = 0;        c.push_back(0);        c.push_back(1);  // 0-9        // 将数打散        while (n != 0) {            int t = n % 10;            num.push_back(t);            n = n / 10;        }        // 计算几位数应该有多少个1        for(int i = 2; i < num.size(); ++i) {            c.push_back(10*c[i-1] + gen10(i - 1));        }        for(int j = 0; j < num.size(); ++j) {            total = total + (num[j]) * c[j];            // 大于1            if (num[j] > 1) {                total += gen10(j);            }            // 为1              if (num[j] == 1) {                int tmp = 0;                for (int k = j - 1; k >= 0; --k) {                    tmp = tmp * 10 + num[k];                }                total += tmp;                total += 1;            }        }        return total;    }    // 10的多少次方    int gen10(int i) {        int t = 1;        for(int j = 0; j < i; ++j) {            t*= 10;        }        return t;    }};

网上同样思路,不过公式化
以算百位上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)

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

http://www.2cto.com/kf/201507/415690.html

0 0
原创粉丝点击