数字子串的总和

时间:2010-12-20 07:48:23

标签: java algorithm complexity-theory big-o

查找数字子串总和的最佳解决方案是什么?

例如,Sum(123)= 1 + 2 + 3 + 12 + 23 + 123 = 164。

我认为是O(n ^ 2)。因为

sum = 0
for i in number: // O(n)
    sum += startwith(i) // O(n)
return sum

任何最佳解决方案?什么是最好的方法?

这是我的解决方案,但是O(n ^ 2):

public static int sumOfSubstring(int i) {
  int sum = 0;

  String s = Integer.toString(i);

  for (int j = 0, bound = s.length(); j < bound; j++) {
   for (int k = j; k < bound; k++) {
    String subString = s.subSequence(j, k + 1).toString();
    sum += Integer.valueOf(subString);
   }
  }

  return sum;
 }

6 个答案:

答案 0 :(得分:13)

观察:

  • 对于数字XY,您有11X + 2Y。
  • 对于数字XYZ,您有111X + 22Y + 3Z。
  • 对于WXYZ,你有1111W + 222X + 33Y + 4Z。

这是我的C#实现,尽管移植到Java应该是微不足道的:

static long SumSubtring(String s)
{
    long sum = 0, mult = 1;
    for (int i = s.Length; i > 0; i--, mult = mult * 10 + 1)
        sum += (s[i - 1] - '0') * mult * i;
    return sum;
}

请注意,它实际上是O(n)。

答案 1 :(得分:4)

对于长度为n的给定字符串,肯定有~N ^ 2个可能的子串。但是,我们可以使用以下等式计算线性时间的总和:

alt text

S代表数字序列(s0,s1,s2,...,sn)。

对于S =&lt; 1,2,3&gt;它返回111 * 1 + 22 * 2 + 3 * 3 = 164

请注意,如果我们事先或在循环过程中逐步计算N次幂,则运行时间为线性

答案 2 :(得分:1)

正如@Gabe所说,你可以这样做:

A0 = 1,
A1 = A0*10 + 1,
...
An-1 = An-2 * 10 + 1,

你可以在O(n)中计算A0-An

a[0] = 1;
for (int i=1;i<n;i++)
 a[i] = a[i - 1] * 10 + 1;

现在计算b [i]:

b[0] = a[0] * n
b[1] = a[1] * (n-1)
...

你可以计算O(n)

中的所有b [i]

现在有些是 [伪代码]

for (int i=0;i<n;i++)
   sum += S[n-i - 1] * b[i]

答案 3 :(得分:1)

以上所有答案看起来都很棒。我最近解决了类似的问题。上面给出的公式运行良好,但正如您所看到的那样,字符串的长度增加,计算变得困难,解决方案确实很大。通常当字符串的长度非常大时,你会被要求在MOD之后给出一个大数字说1000000007的答案。所以现在你可以使用一点点的模数算法轻松地计算这些值,或者是特定的Modular exponentiationMultiplicative inverse。因此,修改大输入后的新公式可以写成。 做出假设。

  • Modular_exp()是计算^ b%c
  • 的值的函数
  • 乘法逆变量是9的乘法逆,它是111111112,可以使用相同的modular_exp()函数找到它,但在这里我只是对它进行了硬编码。
  • len是仅包含来自&#39; 0&#39;的字符串的总长度。到&#39; 9&#39;;

以下是代码:

FOR(i, len) {
    coef = (( ( modular_exp(10, len - i, MOD) - 1) * multiinverse ) % MOD) * (i + 1) % MOD;
    res += ( coef * (s[i] - '0') ) % MOD;
}
printf("%lld\n", res % MOD );

那就是它。

答案 4 :(得分:0)

FWIW为N位数添加的整数数量似乎为

N + N-1 + N-2 ... 1

这是一个三角形数字(相当于阶乘的附加值) http://en.wikipedia.org/wiki/Triangular_number

添加数量 N ^ 2 + N / 2

但是,这并不考虑拆分数字所需的工作

答案 5 :(得分:0)

不是一个新答案,而是详细阐述了Gabe给出的接受答案。

说数字是19然后总和是

1+9+19
= 1+ 9 + (10*1+9)
= 11*1 + 2*9

如果number为486则sum为

= 4 + 8 + 6 + 48+ 86 +486
= 4 + 8 + 6 + (10*4+8) + (10*8+6) + (100*4+10*8+6)
= 111*4+22*8+3*6

所以一般来说,如果一个数字表示为一串数字&#34; XY&#34;那么子串的总和将是bw,该数字可以计算为

sum of XY  = X +Y + (10X+Y) 
= 11X+2Y

sum of XYZ = X + Y + Z + (10X + Y)+ (10 Y+ Z) + (100X+ 10Y+Z)
= 111X+22Y+3Z

sum of XYZW = x+ y+ z + w + (10x + y) + (10y+ z)+ (10z+ w)+(100X+ 10Y+Z)+(100y+ 10z+w)+(1000x+100y+10z+w)
=1111x+222y+33z+4w

对于9位数字和

(9 times 1)*1st + (8 times 2)*2nd+ (7 times 3)*3rd + (6 times 4)*4th+(5 times 5)*5th +(4 times 6)*6th  +(3 times 7)*7th+(3 times 8)*8th+(3 times 9)*9th