algorithm - 求1到N所有数字的位数之和

标签 algorithm math big-o

<分区>

问题: 求1到N(包括两端)所有数字的位数之和

时间复杂度应该是 O(logN)

对于 N = 10,总和为 1+2+3+4+5+6+7+8+9+(1+0) = 46

对于 N = 11,总和为 1+2+3+4+5+6+7+8+9+(1+0)+(1+1) = 48

对于 N = 12,总和为 1+2+3+4+5+6+7+8+9+(1+0)+(1+1) +(1+2)= 51

这个递归 solution工作起来很有魅力,但我想了解达成这种解决方案的基本原理。我相信它是基于有限归纳法,但有人可以确切地展示如何解决这个问题吗?

我已粘贴(稍作修改)上述解决方案:

static long Solution(long n)
{
    if (n <= 0)
        return 0;
    if (n < 10)
        return (n * (n + 1)) / 2; // sum of arithmetic progression
    long x = long.Parse(n.ToString().Substring(0, 1)); // first digit
    long y = long.Parse(n.ToString().Substring(1)); // remaining digits
    int power = (int)Math.Pow(10, n.ToString().Length - 1);

    // how to reach this recursive solution?
    return (power * Solution(x - 1))
    + (x * (y + 1)) 
    + (x * Solution(power - 1)) 
    + Solution(y);
}

单元测试(不是 O(logN)):

    long count = 0;
    for (int i=1; i<=N; i++)
    {
        foreach (var c in i.ToString().ToCharArray())
            count += int.Parse(c.ToString());
    }

或者:

Enumerable.Range(1, N).SelectMany(
    n => n.ToString().ToCharArray().Select(
        c => int.Parse(c.ToString())
    )
).Sum();

最佳答案

这实际上是一个 O(n^log10(2)) 时间的解决方案(log10(2) 大约是 0.3)。不确定这是否重要。我们有 n = xy,我在这里使用 concatenation 来表示串联,而不是乘法。下面是四个关键行,下面有注释。

return (power * Solution(x - 1))

这计算了 x 位置对从 1(含)到 x*power(不含)的数字的贡献。此递归调用不会增加复杂性,因为它会在恒定时间内返回。

+ (x * (y + 1))

这计算了 x 位对从 x*power(含)到 n(含)的数字的贡献。

+ (x * Solution(power - 1))

这计算了从 1(含)到 x*power(不含)的数字的低位贡献。此调用的号码比 n 短一位。

+ Solution(y);

这计算了从 x*power(含)到 n(含)的数字的低位贡献。此调用的号码比 n 短一位。

我们通过应用主定理的情况 1 得到时间限制。为了将运行时间降低到 O(log n),我们可以分析地计算 Solution(power - 1)。我不记得封闭形式是什么。

关于algorithm - 求1到N所有数字的位数之和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35638016/

相关文章:

algorithm - 在图中寻找哈密顿循环的动态规划算法是什么?

algorithm - 为什么 Eric Lippert 的不可变二叉树中没有循环?

algorithm - 图中的索林算法

javascript - 为什么~0是-1?

Java:帮助进行基本输出基本值算术。输出为0,不知道为什么?

python - 输入 343 时完美整数求值失败

c++ - 递归的 Theta 运行时

c - 向后递增数组中的值

algorithm - 以大 O 表示法 N 翻倍时的运行时间比率

algorithm - 难以弄清楚这些棘手的 Big-O 示例