algorithm - 计算给定范围内具有唯一数字的所有数字

标签 algorithm dynamic-programming

这是一道面试题。计算 [1, N] 范围内具有唯一数字(十进制)的所有数字。

显而易见的解决方案是测试范围内的每个数字是否唯一。我们还可以生成所有具有唯一数字的数字(作为排列)并测试它们是否在范围内。

现在我想知道是否有针对这个问题的DP(动态规划)解决方案。

最佳答案

我在想:

Number of unique digits numbers 1-5324
=   Number of unique digits numbers 1-9
  + Number of unique digits numbers 10-99
  + Number of unique digits numbers 100-999
  + Number of unique digits numbers 1000-5324

所以:

f(n) = Number of unique digits numbers with length n.
f(1) = 9 (1-9)
f(2) = 9*9 (1-9 * 0-9 (excluding first digit))
f(3) = 9*9*8 (1-9 * 0-9 (excluding first digit) * 0-9 (excluding first 2 digits))
f(4) = 9*9*8*7

将以上所有内容相加,直到 N 减去 1 的位数为止。

那么你只需要做 Number of unique digits numbers 1000-5324

和:

Number of unique digits numbers 1000-5324
=   Number of unique digits numbers 1000-4999
  + Number of unique digits numbers 5000-5299
  + Number of unique digits numbers 5300-5319
  + Number of unique digits numbers 5320-5324

所以:

N = 5324

If N[0] = 1, there are 9*8*7 possibilities for the other digits
If N[0] = 2, there are 9*8*7 possibilities for the other digits
If N[0] = 3, there are 9*8*7 possibilities for the other digits
If N[0] = 4, there are 9*8*7 possibilities for the other digits
If N[0] = 5
  If N[1] = 0, there are 8*7 possibilities for the other digits
  If N[1] = 1, there are 8*7 possibilities for the other digits
  If N[1] = 2, there are 8*7 possibilities for the other digits
  If N[1] = 3
    If N[2] = 0, there are 7 possibilities for the other digits
    If N[2] = 1, there are 7 possibilities for the other digits
    If N[2] = 2
      If N[3] = 0, there is 1 possibility (no other digits)
      If N[3] = 1, there is 1 possibility (no other digits)
      If N[3] = 2, there is 1 possibility (no other digits)
      If N[3] = 3, there is 1 possibility (no other digits)

上面是这样的:

uniques += (N[0]-1)*9!/(9-N.length+1)!
for (int i = 1:N.length)
  uniques += N[i]*(9-i)!/(9-N.length+1)!

// don't forget N
if (hasUniqueDigits(N))
  uniques += 1

你真的不需要 DP,因为上面的应该足够快了。

编辑:

上面实际上需要稍微复杂一点(上面的 N[2] = 2 和 N[3] = 2 是无效的)。它需要更像:

binary used[10]
uniques += (N[0]-1)*9!/(9-N.length+1)!
used[N[0]] = 1
for (int i = 1:N.length)
  uniques += (N[i]-sum(used 0 to N[i]))*(9-i)!/(9-N.length+1)!
  if (used[N[i]] == 1)
    break
  used[N[i]] = 1

// still need to remember N
if (hasUniqueDigits(N))
  uniques += 1

关于algorithm - 计算给定范围内具有唯一数字的所有数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15155165/

相关文章:

java - 如何在没有错误 ArrayIndexOutOfBoundsException 的情况下实现具有 4 向分区的合并排序算法?

c# - 查找出现在所有列表(或数组或集合)中的值

performance - 分布式局部聚类系数算法(MapReduce/Hadoop)

java - `n` 一袋沙子并插入盒子,算法

Groovy - 将列表扩展为闭包参数

algorithm - 动态编程:允许互换时安装路灯

python - 精确变化算法

algorithm - 在二进制矩阵中查找 "generalized diagonal"

algorithm - 查找棒材切割的价格

c++ - 使用动态编程从数组的左上角到右下角元素