算不了字符串

时间:2016-08-13 07:48:12

标签: algorithm data-structures

在我们的展示位置的公司编码轮询中提出了这个问题。

给定一个由1到9的数字组成的字符串。我们必须排列字符串,使其分成组。我们需要数不。可能的串,使得组的总和< =下一个连续组的总和。

例1
输入:1234
输出:6
字符串是:

  • {1,2,3,4}
  • {1,2,34}
  • {12,3,4}
  • {12,34}
  • {1234}
  • {1234}

此处的第一组合,1 <2 <3 <4。第二种组合,1&lt; 2&lt;(3 + 4)。等等。

例2
输入:516
输出:3
字符串是:

  • {5,16}
  • {51,6}
  • {516}

现在用蛮力方式生成所有字符串的时间是O(2 ^(n-1))。 我的问题是如何以比蛮力更好的方式解决它?

约束:输入字符串长度1&lt; = n&lt; = 1000

1 个答案:

答案 0 :(得分:2)

使用Dynamic Programming可以有效地解决此问题。我使用名为dp的二维数组解决了它。要查找end个字符最后且最后一个字符串从start个字符开始的有效分割数,我们需要使用先前计算和缓存的值来表示有效分割数的结束在start-1角色。该数字是dp[prev_start][start - 1]中所有缓存值的总和,其中prev_start可以是[0, start)之间的任何值,这样s[prev_start:start-1]中的元素总和不会大于s[start:end] Python3中元素的总和。以下是def get_count(s): N = len(s) # Initialize memoization matrix # First row all ones, all others zeros dp = list() dp.append([1] * N) for i in range(N - 1): dp.append([0] * N) # Convert characters to integers s = [ord(i) - ord('0') for i in s] for start in range(1, N): for end in range(start, N): for prev_start in range(0, start): if sum(s[prev_start:start]) <= sum(s[start:end+1]): dp[start][end] += dp[prev_start][start - 1] return sum([dp[i][N - 1] for i in range(N)]) print(get_count('516')) 中的解决方案:

{{1}}

注意:时间复杂度为O(n ^ 4),但您可以轻松地将其优化为O(n ^ 3)。