Tony's Log

Algorithms, Distributed System, Machine Learning

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Marked as mathematics problem, but if you are able to divide 1s into several cases, the AC code becomes natural.

class Solution 
{
    unordered_map<long long, int> memo;
public:
    int countDigitOne(int n) 
    {
        if (n < 10) return n < 1 ? 0 : 1;
        if (memo.find(n) != memo.end())    return memo[n];

        int base = pow(10, floor(log10(n)));
        int v = n / base;
        int r = n % base;

        int cnt0 = countDigitOne(base - 1);
        int cnt1 = 0;
        if (v == 1)
        {
            cnt1 = r + 1;
        }
        else
        {
            cnt1 = base + cnt0;
            cnt1 += (v - 2) * cnt0;
        }

        int ret = cnt0 + cnt1 + countDigitOne(r);
        memo[n] = ret;
        return ret;
    }
};

Lesson learnt: visualization in mind is always helpful.

And this link is amazing: https://leetcode.com/discuss/44281/4-lines-o-log-n-c-java-python - Count it digit by digit.

posted on 2015-07-08 14:45  Tonix  阅读(185)  评论(0编辑  收藏  举报